【问题标题】:Qt QThread trouble using signal/slot going from worker to guiQt QThread使用从worker到gui的信号/插槽出现问题
【发布时间】:2011-12-14 10:16:13
【问题描述】:

我有一个使用 Qt Creator 和随附的 GUI 工具开发的 Qt 应用程序。我有一个主线程 TheGui 和一个由主线程创建的工作线程 WorkerThread(称为 thread)。

我遇到的问题是当我使用在 GUI 中创建一个插槽时

public slot:
  void updateTable(string str);

在 GUI 的头文件和工作线程头文件中的信号 void sendList(string str); 中,插槽永远不会被调用。我将两者连接使用

connect(&thread, SIGNAL(sendList(string str),
        this,    SLOT(updateTable(string str)));

在 GUI cpp 文件的构造函数中。我做了类似的事情,除了工作线程中的插槽和来自 GUI 的信号,它工作正常。我通过使用调试器知道确实调用了信号 sendList,它只是永远不会进入它。

有什么想法吗?

【问题讨论】:

标签: c++ qt qthread


【解决方案1】:

确定确实建立了连接?如果 connect 调用有任何问题,cerr 上通常会有一些关于它的调试输出。

其次,我认为你有一个错字 - 如果你从代码中复制了 connect 调用,那么知道你在 SIGNAL 周围缺少括号 - 应该是

connect(&thread, SIGNAL(sendList(string)), this, SLOT(updateTable(string)));

第三,您作为信号/插槽参数传递的是什么?是 std::string 吗?线程之间的连接必须是排队连接。排队连接只能用作使用Q_DECLARE_METATYPE 宏声明并使用qRegisterMetaType 注册的类型的参数。据我所知,Qt 默认情况下不会为std::string 声明那些,因为它更喜欢QString。如果您没有将这些添加到代码中,则可能是失败的原因。

【讨论】:

    【解决方案2】:
    1. 因为信号和槽位于不同的线程上,所以它们之间的连接具有Qt::QueuedConnection 类型。对于排队连接,Qt 必须能够保存信号参数的副本,以便稍后将它们传递给插槽。
      因此,要通知 Qt 该类型是可复制的,您必须将其注册到 Qt 的元对象系统(参见 QMetaType),如下所示:

      // This macro call should be put in one of your .h files 
      Q_DECLARE_METATYPE(std::string)
      
      // You should call this function before any (queued) 
      // signal/slot connection involving the type
      qRegisterMetaType<std::string>();
      
    2. 参数名称不应包含在QObject::connect 调用中,类型名称应与您传递给Q_DECLARE_METATYPE 的名称完全相同:

      connect(&thread, SIGNAL(sendList(std::string), this, SLOT(updateTable(std::string)));
      

    您还可以使用已经注册的QStringQByteArray,而不是std::string,因为这些函数是槽和信号,因此已经是Qt 特定的。

    【讨论】:

    • 感谢您的回复!我实际上是通过使用指针暂时解决了这个问题。我会在哪里调用 qRegisterMetaType?我不断收到错误“从 'int qMetaTypeId(T*)[with T=StringVector]' 实例化”,其中 StringVector 是我要声明的内容。
    • @Kyle 也许您没有在调用 qRegisterMetaType 的 .cpp 文件中包含使用 Q_DECLARE_METATYPE 的头文件。
    • 页眉中是否有需要放置的地方?在 Q_OBJECT 下?此外,我已切换到使用 QVector 并使用插槽传递它。根据我一直在查看的文档,这也不是自动注册的?
    • Q_DECLARE_METATYPE 应该在任何类声明之外。您可以使用 QStringList 代替应该注册的。
    • 原来问题是我需要在
    猜你喜欢
    • 2020-10-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    相关资源
    最近更新 更多