“这与上述预期用途相矛盾。我错过了什么吗?”
是的,我认为您误解了线程亲和性(对象正在运行的线程)的概念。
让我们以最少的代码为例:-
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
假设这段代码是从一个线程亲和性为主线程的对象创建的,例如QMainWindow
,线程对象pThread
在主线程上运行;它的线程亲和性是主线程。
相反,QObject
派生MyObject
实例myObj
已移至新线程pThread
。所以,线程亲和性myObj
现在是新线程。
“为”编写的函数QThread
仍然直接从主线程调用,因为它是在主线程运行的。
将QThread
其视为线程控制器对象,而不是线程本身。这是通常不鼓励从 继承的原因之一QThread
,除非您想更改QThread
管理底层线程的方式。
一个线程中怎么会有多个事件循环?...
我自己并没有直接使用它,但我会尽力解释这一点。也许其他人将能够纠正或确认这一点。从QEventLoop 的 Qt 文档中,它指出: -
在任何时候,您都可以创建一个QEventLoop
对象并调用exec()
它来启动一个本地事件循环。
QEventLoop exec 的签名是:-
int QEventLoop::exec ( ProcessEventsFlags 标志 = AllEvents )
因此,如果您传入一组标志,则只会处理这些事件。现在,随着调用exec()
开始处理事件,直到exit()
被调用,您可以创建一个本地事件循环,让您的程序等待一个或多个特定事件发生。
第二个事件循环是主事件循环中的本地事件循环,但由于每个事件循环可以处理整个事件队列,该队列由线程中的所有事件循环共享,它可以用于覆盖主事件的事件处理环形。
如果您将事件循环概念化为执行以下操作(伪代码):-
QList<QEvent*> eventList;
while(!stop)
{
// handle events in eventList
}
然后,第二个事件循环将执行此操作:-
bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
// handle events in eventList
...
...
// Inner event loop
bool bStop = false;
while(!bStop)
{
// handle events in eventList
}
}