0

我有几个客户端 GUI 窗口都源自QMainWindow. 每个窗口都可能执行不同的任务,但都从实现为QThread.

所有客户端都连接到slot数据缓存中的同一个,然后发出signals 来提示数据缓存做某事。数据缓存的signals 排队,因此数据缓存一次只做一件事。

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

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

4

1 回答 1

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 版本有一个错误QPointer,会导致多线程上下文中的崩溃。如果您想这样做,请使用更新版本的 Qt。

我希望这很清楚。

于 2012-08-17T22:02:36.747 回答