class MyThread : public QObject{
Q_OBJECT
void work(){
qDebug()<<"MyThread::work() thread id: "<<QThread::currentThreadId()<<"\n";
}
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
qDebug()<<"main thread id: "<<QThread::currentThreadId()<<"\n";
QThread* subThread = new QThread;
MyThread* my_thread = new MyThread;
my_thread->moveToThread(thread1);
my_thread->start();
qDebug()<<"00000000";
my_thread->work();
connect(ui->pushButton, &QPushButton::clicked, my_thread, &MyThread::work);
connect(ui->pushButton, &QPushButton::clicked, this, [=]{
qDebug()<<"11111111";
my_thread->work();
});
connect(ui->pushButton, &QPushButton::clicked, my_thread, [=]{
qDebug()<<"22222222";
my_thread->work();
});
}
程序执行结果:
main thread id: 0x1a70
00000000
MyThread::work1() thread id: 0x1a70
11111111
MyThread::work1() thread id: 0x1a70
MyThread::work1() thread id: 0x698
22222222
MyThread::work1() thread id: 0x698
请问为什么主窗口直接调用 my_thread->work(),conncet(ui->pushbuton, &QPushButton::clicked, this, [=]{my_thread->work() ;});两者都是在主线程中执行,而另外两个调用在子线程中正确执行?
将问题中的代码问题放在一边,规则是连接到信号的代码在创建/移动到 receiver 对象(而不是发射器)的线程中执行(至少默认情况下,更多稍后再说)。
除了直接调用
work
方法的一种情况外,所有连接都是通过 Qt::AutoConnection
完成的。引用:
如果接收器位于发出信号的线程中,则使用 Qt::DirectConnection。否则,使用 Qt::QueuedConnection。连接类型在信号发出时确定。
然后:
this
(MainWindow
)是在主线程中创建的(QWidget
的实例只能在主线程中创建,不能移动),因此:
my_thread->work();
从主线程调用。 connect(ui->pushButton, &QPushButton::clicked, this, [=]{ ... });
将在主线程中执行lambda。 (由于 ui->pushButton
和 this
,QWidget
的两个实例都位于同一个线程中,因此它实际上是 Qt::DirectConnection
)my_thread
(MyThread*
) 已在主线程中创建,然后移至工作线程。
connect(ui->pushButton, &QPushButton::clicked, my_thread, &MyThread::work);
实际上是 Qt::QueuedConnection
,因此 work
将从工作线程执行。connect(ui->pushButton, &QPushButton::clicked, my_thread, [=]{ ...});
是等价的,即将从工作线程执行。对于后 2 个连接,您可以使用
work
强制 Qt::DirectConnection
/lambda 从主线程执行。最终细节:
Qt::DirectConnection
连接的方法/lambda(无论是显式的还是通过 Qt::AutoConnection
)都会立即执行,即:在 emitter 的线程中(根据链接文档,又名 signalling thread),并且无需等待返回事件循环。Qt::QueuedConnection
连接的方法/lambda 在执行之前会有一些延迟,因为您必须等待事件循环执行。这就是输出按照您在函数中呈现的方式排序的原因:排队的连接落后于直接连接。
如果一切都是
Qt::DirectConnection
,则事情将以您连接它们的相同顺序执行。