Qt QT使用从工作人员到gui的信号/插槽故障

时间:2011-10-24 19:42:46

标签: c++ qt qthread

我有一个Qt应用程序,它是使用Qt Creator和它附带的GUI工具开发的。我有一个主线程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确实被调用,它永远不会进入它。

有什么想法吗?

2 个答案:

答案 0 :(得分: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)));
    
  3. 您还可以使用已注册的QStringQByteArray,而不是std::string,因为这些功能是广告位和信号,因此已经是Qt特定的。

答案 1 :(得分:1)

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

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

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

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