1

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

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

public slot:
  void updateTable(string str);

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

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

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

有什么想法吗?

4

2 回答 2

4
  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)));
    

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

于 2011-10-24T21:36:47.203 回答
1

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

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

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

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

于 2011-10-24T21:25:21.450 回答