2011-10-24 68 views
1

我有一个使用Qt Creator和随附的GUI工具开发的Qt应用程序。我有一个主线程TheGui和由主线程WorkerThread(称为thread)创建的工作线程。Qt QThread使用从工作人员到gui的信号/插槽出现问题

时遇到的问题是,当我通过使用

public slot: 
    void updateTable(string str); 

工作线程的标题文件内的GUI和信号void sendList(string str);的头文件内创建从未在GUI的槽,所述槽被调用。我连接两个使用

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

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

有什么想法?

+0

请参阅http://stackoverflow.com/questions/4927860/how-to-pass-variables-to-slot-methods-in-qt –

回答

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

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

+0

感谢您的回应!我实际上通过使用指针来解决这个问题。我在哪里可以调用qRegisterMetaType?我不断收到错误'从'int qMetaTypeId(T *)[与T = StringVector]'实例化'其中StringVector是我想要声明的。 –

+0

@Kyle也许你没有在你使用qRegisterMetaType的.cpp文件中使用Q_DECLARE_METATYPE的头文件。 – alexisdm

+0

在标题中是否需要放置它?在Q_OBJECT下?另外,我已经切换到使用QVector 并通过使用插槽。根据我一直在看的文档,这不是自动注册? –

1

确定连接实际上是由?如果连接呼叫有任何问题,通常在cerr上有关于它的一些调试输出。

其次,我认为你有一个错字 - 如果你复制了你的代码连接调用,然后知道你有括号周围信号欠缺 - 应该是

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

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