Qt QThread 使用从工作线程到 gui 的信号/槽时出现问题

发布于 2024-12-11 19:29:41 字数 662 浏览 0 评论 0原文

我有一个使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暗藏城府 2024-12-18 19:29:42

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

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

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

第三,你作为信号/槽参数传递的是什么?是 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

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

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 prefers QString. If you didn't add those to your code, it might be the reason for failure.

半步萧音过轻尘 2024-12-18 19:29:41
  1. 由于信号和槽位于不同的线程上,因此它们之间的连接具有 Qt::QueuedConnection 类型。对于排队连接,Qt 必须能够保存信号参数的副本,以便稍后将它们传递到插槽。

    因此,要通知 Qt 该类型是可复制的,您必须将其注册到 Qt 的元对象系统(请参阅 QMetaType) 像这样:

    // 该宏调用应放在您的 .h 文件之一中 
    Q_DECLARE_METATYPE(std::string)
    
    // 您应该在任何(排队)之前调用此函数 
    // 涉及类型的信号/槽连接
    qRegisterMetaType();
    
  2. 参数名称不应包含在 QObject::connect 调用中,并且类型名称应与你传递给的人Q_DECLARE_METATYPE

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

您还可以使用已经注册的QStringQByteArray,而不是std::string,因为这些函数是插槽和信号等已经是 Qt 具体的。

  1. 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:

    // 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. 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 to Q_DECLARE_METATYPE:

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

You can also use QString or QByteArray, which are already registered, instead of std::string, since these functions are slots and signals and as such are already Qt specific.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文