如何在 Qt 中的另一个线程中发出插槽信号
How to signal a slot in another thread in Qt
我使用 Qt 编写了一个简单的信号槽应用程序。我想发送一个信号给另一个运行在主线程之外的线程。
这是我的代码:
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();
};
但是 returns:
0x7f9851c988c0
0x7f9851c988c0
如何调用输出另一个 threadID 的信号?
实现 Thread1
构造函数,如下所示:
Thread1(QObject* parent) { moveToThread(this); }
你搞反了。 QThread
是线程句柄,而不是线程本身。如果你想 运行 另一个线程中的某些东西,它属于你移动到一个线程的普通 QObject
。您根本不需要从 QThread
派生!您也不应该将 QThread
的基础 QObject
移动到线程本身。您所做的是在线程本身中拥有一个线程句柄。线程一结束,句柄就无法正常工作(QObject
和 null thread()
)。
首先,如果您只需要 运行 一些代码 运行 在工作线程中完成(例如,进行计算),请使用线程池和 QtConcurrent
框架。它为您管理所有线程:
#include <QtConcurrent>
...
QThread::currentThread()->setObjectName("main");
qDebug() << QThread::currentThread();
QtConcurrent::run([]{ qDebug() << QThread::currentThread(); }
如果您坚持要自己控制线程的生命周期,您将执行以下操作:
#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
class 知道如何在传递指向 QObject
的指针时输出对象的地址、class 和名称(如果已设置) .因此,您不需要使用 QThread::currentThreadId()
,QThread::currentThread()
就足够了——而且您可以为线程提供助记名称,毕竟它们是 QObject
。
我使用 Qt 编写了一个简单的信号槽应用程序。我想发送一个信号给另一个运行在主线程之外的线程。
这是我的代码:
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();
};
但是 returns:
0x7f9851c988c0
0x7f9851c988c0
如何调用输出另一个 threadID 的信号?
实现 Thread1
构造函数,如下所示:
Thread1(QObject* parent) { moveToThread(this); }
你搞反了。 QThread
是线程句柄,而不是线程本身。如果你想 运行 另一个线程中的某些东西,它属于你移动到一个线程的普通 QObject
。您根本不需要从 QThread
派生!您也不应该将 QThread
的基础 QObject
移动到线程本身。您所做的是在线程本身中拥有一个线程句柄。线程一结束,句柄就无法正常工作(QObject
和 null thread()
)。
首先,如果您只需要 运行 一些代码 运行 在工作线程中完成(例如,进行计算),请使用线程池和 QtConcurrent
框架。它为您管理所有线程:
#include <QtConcurrent>
...
QThread::currentThread()->setObjectName("main");
qDebug() << QThread::currentThread();
QtConcurrent::run([]{ qDebug() << QThread::currentThread(); }
如果您坚持要自己控制线程的生命周期,您将执行以下操作:
#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
class 知道如何在传递指向 QObject
的指针时输出对象的地址、class 和名称(如果已设置) .因此,您不需要使用 QThread::currentThreadId()
,QThread::currentThread()
就足够了——而且您可以为线程提供助记名称,毕竟它们是 QObject
。