简体   繁体   English

Qt向移动到线程的对象发出信号

[英]Qt emit signal to object moved to thread

In order to initiate stopping a thread by setting a flag (and then returning from within the thread), I need to communicate with it. 为了通过设置标志(然后从线程内返回)来启动停止线程,我需要与它进行通信。

The threading is implemented like this 线程是这样实现的

MyClass* obj = new MyClass(0);
connect( this,SIGNAL( stop() ),obj, SLOT(stop()));
emit stop();    // slot is called (qDebug output)

MyThread = new QThread;
obj->moveToThread(MyThread);
connect( ... started() ... quit() ... finished() ... deleteLater() ...
....

emit stop();    // slot isn't called (qDebug output)

The slot does not have any logic yet, it just uses a qDebug() output. 该插槽还没有任何逻辑,它仅使用qDebug()输出。 The object creation and connections take place in a main window method. 对象的创建和连接在主窗口方法中进行。

Unfortunately, I can't figure out what I am doing wrong: once the object is moved to the thread, the slot is not run anymore. 不幸的是,我无法弄清楚自己在做什么:将对象移至线程后,插槽将不再运行。

Maybe you just forgot to copy/paste it in, but you're missing a MyThread->start() call. 也许您只是忘了复制/粘贴它,但是您错过了MyThread->start()调用。 Also, the line declaring the thread should be QThread * MyThread = new QThread(); 同样,声明线程的行应该是QThread * MyThread = new QThread(); , but that was probably just a typo. ,但这可能只是一个错字。

Now, in your answer, you say that using a Qt::DirectConnection seems to have fixed your problem. 现在,在回答中,您说使用Qt::DirectConnection似乎已经解决了您的问题。 However, a slot invoked using a direct connection just calls the slot method directly. 但是,使用直接连接调用的插槽仅直接调用slot方法。 The slot method is running, but it's running from the calling thread (where your stop() signal is emitted). slot方法正在运行,但从调用线程(发出stop()信号的位置)运行。 This will work even if your thread isn't started. 即使您的线程未启动,这也将起作用。 What you really want is for the slot to be invoked over a Qt::QueuedConnection . 您真正想要的是通过Qt::QueuedConnection调用插槽。 This will place an event in the worker thread's event loop, which will then invoke the slot. 这将在工作线程的事件循环中放置一个事件,然后将调用该插槽。 Note that Qt will handle the connection type if you don't specify. 请注意,如果您未指定,Qt将处理连接类型。

If the queued connection doesn't work, then you're probably blocking the thread's event loop with your work. 如果排队的连接不起作用,则可能是您的工作阻塞了线程的事件循环。 In your work method, do you ever pass control back to the event loop to allow it to process events? 在您的工作方法中,您是否曾经将控制权传递回事件循环以允许其处理事件? Or does it just run in a while loop waiting for a flag to change state? 还是只是在while循环中运行以等待标志更改状态?

Also, your code doesn't compile/run as-is. 另外,您的代码不会按原样编译/运行。 I assume you're handling the QApplication stuff already - namely, calling QApplication::exec() after everything is set up in you main function. 我假设您已经在处理QApplication东西-即,在您的main功能中设置完所有内容后,调用QApplication::exec() If you don't call exec() , the main event loop is never started. 如果不调用exec() ,则永远不会启动主事件循环。

The debug output actually took place, only after the thread finished its work. 调试输出实际上是在线程完成工作之后才发生的。 Using 使用

connect( this, SIGNAL(stop()), obj, SLOT(stop()), Qt::DirectConnection);

resolved the problem. 解决了问题。

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

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