Qt QThread 使用从工作线程到 gui 的信号/槽时出现问题
我有一个使用 Qt Creator 及其附带的 GUI 工具开发的 Qt 应用程序。我有一个主线程 TheGui
和一个由主线程 WorkerThread
创建的工作线程(称为 thread
)。
我遇到的问题是,当我在 GUI
public slot:
void updateTable(string str);
的头文件中使用并在工作线程的头文件中使用信号 void sendList(string str);
创建一个插槽时,插槽永远不会被调用。 使用了这两个连接
connect(&thread, SIGNAL(sendList(string str),
this, SLOT(updateTable(string str)));
我在 GUI cpp 文件的构造函数中 。我做了类似的事情,除了工作线程中的插槽和来自 GUI 的信号之外,它工作得很好。我通过使用调试器知道信号 sendList 确实被调用,只是永远不会进入它。
有什么想法吗?
I have a Qt application that was developed using Qt Creator and the GUI tool that accompanies it. I have a main thread, TheGui
and a worker thread that is created by the main thread, WorkerThread
(called thread
).
The problem I'm having is when I create a slot in the GUI by using
public slot:
void updateTable(string str);
within the header file of the GUI and signal void sendList(string str);
within the header file of the worker thread, the slot never gets called. I connected the two using
connect(&thread, SIGNAL(sendList(string str),
this, SLOT(updateTable(string str)));
within the constructor in the GUI cpp file. I did something similar except with the slot in the worker thread and signal from the GUI and it worked fine. I know from using the debugger that the signal sendList is indeed getting called, it is just never going into it.
Any thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
确定确实建立了连接吗?如果 connect 调用有任何问题,
cerr
上通常会出现一些有关它的调试输出。其次,我认为你有一个错字 - 如果你从代码中复制了 connect 调用,那么就知道你在 SIGNAL 周围缺少括号 - 应该是
第三,你作为信号/槽参数传递的是什么?是 std::string 吗?线程之间的连接必须是排队连接。排队连接只能使用使用 Q_DECLARE_METATYPE 宏声明的类型作为参数,并且已注册 qRegisterMetaType。据我所知,Qt 默认情况下不会为
std::string
声明这些,因为它更喜欢QString
。如果您没有将这些添加到代码中,则可能会导致失败。Sure that connection is actually made? If there are any problems with connect call, there is usually some debugging output about it on
cerr
.Secondly, I think you have a typo - if you copied connect call from your code, then know that you have parenthesis missing around SIGNAL - should be
Thirdly, what is that you are passing as signal/slot parameter? Is it std::string? Connections between threads must be queued connections. Queued connections can use as parameters only types declared with Q_DECLARE_METATYPE macro, and registered with qRegisterMetaType. As far as I know, Qt by default doesn't declare those for
std::string
, as it prefersQString
. If you didn't add those to your code, it might be the reason for failure.由于信号和槽位于不同的线程上,因此它们之间的连接具有
Qt::QueuedConnection
类型。对于排队连接,Qt 必须能够保存信号参数的副本,以便稍后将它们传递到插槽。因此,要通知 Qt 该类型是可复制的,您必须将其注册到 Qt 的元对象系统(请参阅 QMetaType) 像这样:
参数名称不应包含在
QObject::connect
调用中,并且类型名称应与你传递给的人Q_DECLARE_METATYPE
:您还可以使用已经注册的
QString
或QByteArray
,而不是std::string
,因为这些函数是插槽和信号等已经是 Qt 具体的。Because the signal and the slot are on distinct threads, the connection between them has the
Qt::QueuedConnection
type. And for queued connections, Qt has to be able to save a copy of the signal parameters, to pass them later to the slot.So, to inform Qt that the type is copyable, you have to register it with Qt's meta-object system (see QMetaType) like this:
The parameter name shouldn't be included in the
QObject::connect
call, and the type names should be exactly the same as the ones you passed toQ_DECLARE_METATYPE
:You can also use
QString
orQByteArray
, which are already registered, instead ofstd::string
, since these functions are slots and signals and as such are already Qt specific.