Rak*_*kib 3 c++ qt qthread qobject qeventloop
我正在浏览链接
\n\n\n\n我对一些说法感到困惑。在第一个链接中,它说
\n\n\n\n\nQThread 中的所有函数都是编写的,旨在从创建线程调用,而不是从 QThread 启动的线程调用。
\n
虽然它建议使用moveToThread将对象移动到新线程,而不是子类化QThread。我的问题是:
run方法调用的默认实现exec,会创建一个事件循环,当使用 改变对象的线程关联性moveToThread时,所有的操作slots都会在新线程中执行,而不是在创建线程上执行,这与前面提到的预期用途相矛盾相矛盾。我错过了什么吗?
第二个问题:
\n\n在第三个链接中说
\n\n\n\n\n事件队列属于线程而不是事件循环,并且它\xe2\x80\x99被该线程中运行的所有事件循环共享。
\n
我的问题是单个线程中如何可以有多个事件循环?我的理解是,事件循环通过事件队列循环,直到exit/terminate被调用,并处理每个event到达该队列的事件。如果这是真的,一个循环将永远不会结束(除非 exit/terminate被调用),另一个循环如何开始?任何演示它的示例代码都将受到高度赞赏。
“这与上述预期用途相矛盾。我错过了什么吗?”
是的,我认为您误解了线程关联性(对象正在其上运行的线程)的概念。
让我们以最少的代码为例:-
QThread* pThread = new QThread; // QThread on the main thread
MyObject* myObj = new MyObject; // MyObject on the main thread
myObj->moveToThread(pThread); // MyObject on the new thread, controlled by pThread
pThread->start(); // pThread instance is still on the main thread
Run Code Online (Sandbox Code Playgroud)
假设这段代码是从一个线程亲和性为主线程的对象创建的,例如QMainWindow,该线程对象pThread正在主线程上运行;它的线程亲和力是主线程。
相反,QObject派生MyObject实例myObj已移至新线程pThread。因此,线程亲和力myObj现在是新线程。
“为QThread”编写的函数仍然直接从主线程调用,因为主线程就是它运行的地方。
将其视为QThread线程控制器对象,而不是线程本身。这是通常不鼓励继承的原因之一QThread,除非您想更改QThread管理底层线程的方式。
一个线程中如何可以有多个事件循环?...
我自己没有直接使用过它,但我会尝试按照我的理解来解释它。也许其他人能够纠正或确认这一点。从Qt Documentation for QEventLoop中,它指出: -
您可以随时创建一个
QEventLoop对象并调用exec()它来启动本地事件循环。
QEventLoop exec 的签名是: -
int QEventLoop::exec ( ProcessEventsFlags 标志 = AllEvents )
因此,如果您传入一组标志,则只会处理这些事件。现在,当调用exec()开始处理事件直到exit()被调用时,您可以创建一个本地事件循环,让您的程序等待一个或多个特定事件发生。
第二个事件循环是主事件循环中的本地事件循环,但由于每个事件循环可以处理整个事件队列,该队列由线程中的所有事件循环共享,因此它可以用于覆盖主事件中的事件处理环形。
如果您将事件循环概念化为执行类似的操作(伪代码):-
QList<QEvent*> eventList;
while(!stop)
{
// handle events in eventList
}
Run Code Online (Sandbox Code Playgroud)
第二个事件循环将执行以下操作:-
bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
// handle events in eventList
...
...
// Inner event loop
bool bStop = false;
while(!bStop)
{
// handle events in eventList
}
}
Run Code Online (Sandbox Code Playgroud)