我有一个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确实被调用,它永远不会进入它。
有什么想法吗?
答案 0 :(得分:4)
由于信号和插槽位于不同的线程上,因此它们之间的连接具有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>();
参数名称不应包含在QObject::connect
调用中,类型名称应与传递给Q_DECLARE_METATYPE
的名称完全相同:
connect(&thread, SIGNAL(sendList(std::string), this, SLOT(updateTable(std::string)));
您还可以使用已注册的QString
或QByteArray
,而不是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
。如果您没有将这些添加到代码中,则可能是失败的原因。