如何在Qt中的另一个线程中发出一个槽 [英] How to signal a slot in another thread in Qt

查看:165
本文介绍了如何在Qt中的另一个线程中发出一个槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一个简单的信号槽应用程序使用Qt。

I have written a simple signal slot application using Qt. I want to send a signal to another thread that is runs out of the main thread.

这里是我的代码:

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

但它返回:

0x7f9851c988c0
0x7f9851c988c0

另一个线程ID?

推荐答案

A QThread 是一个线程句柄,而不是线程本身。如果你想在另一个线程中运行一个东西,它属于一个简单的 QObject ,你移动到一个线程。你不需要派生自 QThread !你也不应该将 QThread 的基础 QObject 移动到线程本身。你所做的是有一个句柄的线程活在线程本身。一旦线程完成,句柄就变得无效了( QObject ,空值 thread())。

You've got it backwards. A QThread is a thread handle, not a thread itself. If you want to run something in another thread, it belongs in a plain QObject that you move to a thread. You don't need to derive from QThread at all! You also shouldn't move a QThread's base QObject to the thread itself. 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()).

首先,如果你需要的是运行一些在工作线程中运行到完成的代码(例如进行计算),使用线程池和 QtConcurrent 框架。它管理你的所有线程:

First of all, if all you need is to run some code that runs to completion (e.g. does a calculation) in a worker thread, use the thread pool and QtConcurrent framework. It manages all the threads for you:

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


b $ b

如果你坚持自己控制线程的生命周期,你可以这样做:

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

最后,注意 QDebug 类知道如何在传递指向 QObject 的指针时输出对象的地址,类和名称(如果设置)。因此,您不需要使用 QThread :: currentThreadId() QThread :: currentThread()足够 - 你可以给线程记忆名称,因为他们 QObject s,毕竟。

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. 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 QObjects, after all.

这篇关于如何在Qt中的另一个线程中发出一个槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆