简体   繁体   English

如何在Qt中发信号通知另一个线程中的插槽

[英]How to signal a slot in another thread in Qt

I have written a simple signal slot application using Qt. 我用Qt编写了一个简单的信号槽应用程序。 I want to send a signal to another thread that is runs out of the main thread. 我想向另一个用完主线程的线程发送信号。

Here is my code: 这是我的代码:

class Thread1 : public QThread
{
    Q_OBJECT


    void run()
    {
        exec();
    }
public:
    Thread1(QObject* parent);

public slots:
    void a()
    {
        qInfo()<<QThread::currentThreadId();
    }
};
class Object : public QObject
{
    Q_OBJECT
public:
    Object(){}
    void start()
    {
        qInfo()<<QThread::currentThreadId();
        Thread1* thread = new Thread1(this);
        connect(this,SIGNAL(a()),thread,SLOT(a()));
        thread->start();
        emit a();
    }

signals:
    void a();
};

But it returns: 但它返回:

0x7f9851c988c0
0x7f9851c988c0

How can I call a signal that outputs another threadID? 如何调用输出另一个threadID的信号?

You've got it backwards. 你已经倒退了。 A QThread is a thread handle, not a thread itself. QThread是一个线程句柄,而不是一个线程本身。 If you want to run something in another thread, it belongs in a plain QObject that you move to a thread. 如果你想在另一个线程中运行某些东西,它属于你移动到一个线程的普通QObject You don't need to derive from QThread at all! 您根本不需要从QThread派生! You also shouldn't move a QThread 's base QObject to the thread itself. 您也不应该将QThread的基础QObject移动到线程本身。 What you do is have a handle to the thread live in the thread itself. 你所做的是拥有线程本身的线程句柄。 As soon as the thread finishes, the handle becomes non-functional (a QObject with a null thread() ). 一旦线程完成,句柄就会QObject (一个带有空thread()QObject thread() )。

First of all, if all you need is to run some code that runs to completion (eg does a calculation) in a worker thread, use the thread pool and QtConcurrent framework. 首先,如果您只需要在工作线程中运行一些运行完成的代码(例如进行计算),请使用线程池和QtConcurrent框架。 It manages all the threads for you: 它管理所有线程:

#include <QtConcurrent>
...
QThread::currentThread()->setObjectName("main");
qDebug() << QThread::currentThread();
QtConcurrent::run([]{ qDebug() << QThread::currentThread(); }

If you insist on controlling the thread's lifetime yourself, you'd do the following: 如果您坚持自己控制线程的生命周期,则执行以下操作:

#include <QtCore>
struct Worker : QObject {
  Q_SLOT void aSlot() { 
    qDebug() << QThread::currentThread(); 
    QThread::currentThread()->quit();
  }
  Q_SIGNAL void aSignal();
  Q_OBJECT
};

int main(int argc, char ** argv) {
  QCoreApplication app{argc, argv};
  QThread::currentThread()->setObjectName("main");
  QThread thread;
  thread.setObjectName("thread");
  Worker a, b;
  b.moveToThread(&thread);
  thread.start();
  QObject::connect(&a, &Worker::aSignal, &b, &Worker::aSlot);
  emit a.aSignal(); // the signal is emitted from the main thread
  thread.wait();
}

Finally, note that the QDebug class knows how to output the object's address, class and name (if set) when passed a pointer to a QObject . 最后,请注意QDebug类在传递指向QObject的指针时知道如何输出对象的地址,类和名称(如果设置)。 Thus, you don't need to use QThread::currentThreadId() , the QThread::currentThread() is sufficient - and you can give the threads mnemonic names since they are QObject s, after all. 因此,您不需要使用QThread::currentThreadId()QThread::currentThread()就足够了 - 您可以为线程提供助记名称,因为它们毕竟是QObject

实现Thread1构造函数如下:

Thread1(QObject* parent) { moveToThread(this); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM