Qt 4.7向特定线程发送信号

时间:2012-08-17 16:42:36

标签: qt

我有几个客户端GUI窗口都来自QMainWindow。每个窗口都可能执行不同的任务,但所有窗口都要求实现为QThread的中央缓存中的数据。

所有客户端都连接到数据缓存中的相同slot,然后发出signal以提示数据缓存执行某些操作。数据高速缓存的signal排队,因此数据高速缓存一次只做一件事。

当数据缓存完成时,它需要通知正确的客户端它正在做的事情已经完成。我的直接想法是向请求客户端发出关于完成的signal。这意味着要连接到特定客户的slot,然后向其发送signal

我是否必须连接然后断开与客户端的连接?我知道获得供应商的QObject::sender()功能。是否有某种方式只向该发送方(客户端)发送信号?还是有其他方法可以做到这一点吗?

1 个答案:

答案 0 :(得分:0)

您可以采取更简单的方法来解决问题。例如,我会考虑调查QtConcurrent框架。或者,您也可以重新设计您的设计,以便客户端在请求缓存执行任何操作之前首先连接到缓存上的“已完成”信号。如果失败了,您可能还会考虑依赖QMetaObject::invokeMethod功能(适用于您的客户端或缓存)。此函数允许您使用任意泛型参数(以线程安全的方式)在任意QObject上调用任意方法(假设您有指向它的指针)。

如果您使用QMetaObject::invokeMethod方法,则应注意一些缺点。首先,您必须使用其字符串名称调用该方法,这意味着如果您使用了错误的名称,则无法在编译时找到该方法。其次,由于您的客户端具有与中央缓存不同的线程关联,因此当缓存调用它们上的方法时,客户端可能已被销毁(尽管在您的情况下,这对您来说不是问题) 。最后,您可能不希望缓存知道必须在其客户端上执行的方法的名称。

我没有任何解决第一个缺点的方法(我不确定在即将到来的Qt 5.0版本中是否会以不同方式处理)。至于第二个和第三个问题,我建议创建一个封装对方法的引用的对象 - 如下所示:

class MethodReference
{
   MethodReference(QObject* object, const QString& methodName);

   ...

   bool invoke(QGenericArgument val0 = QGenericArgument(),
               QGenericArgument val1 = QGenericArgument(),
               ...
               QGenericArgument val9 = QGenericArgument());

private:
   QPointer<QObject> mObject;
   QString mMethod;
};

然后,您将从客户端将此对象传递到缓存。然后缓存调用此对象的调用。

请注意QPointer的使用 - 这为您提供了一种线程安全的方法,可以在尝试调用对象之前检查对象是否已被销毁。由于我之前已经完成了这个,我还会告诉您,4.8之前的Qt版本有一个bug in QPointer会导致多线程上下文崩溃。如果你想这样做,请使用更新版本的Qt。

我希望这很清楚。