我能否确定一个线程是否有QEventLoop?

7
我正在编写一个Windows DLL,可能在QApplication下运行,也可能在常规Win32应用程序下运行。我想使用Qt网络类,这需要一个事件循环。
如果在常规Win32(非Qt)应用程序中运行,则必须启动QThread或QEventLoop以使Qt网络信号和槽正常工作。注意:DLL使用QtWinMigrate。 但如果在QApplication中运行,则已经存在一个事件循环,无需启动新的QThread。
有没有一种方法可以检查现有的QEventLoop?
澄清: 该DLL运行在大型遗留代码库下,我的类所在的线程可能是或可能不是QThread。

1
你不能检查 QApplication::instance 是否存在吗? - peppe
1
似乎所有的QThread都有一个事件循环,所以这里的重要问题是它是否正在运行。也许可以用isRunning()来判断? - dtech
我刚刚对问题进行了澄清。因为我们正在使用QtWinMigrate,所以QApplication::instance是存在的。但我的类可能在非QThread工作线程中运行,并且没有事件循环。这样说通了吗?抱歉,我还在努力理解它。也许这没有关系,我应该始终启动一个新的QThread? - Matthew
有一个函数:bool QEventLoop::isRunning() const,如果事件循环正在运行,则返回true;否则返回false。从调用exec()到调用exit()之间的时间被认为是事件循环正在运行。问题是,你能访问事件循环吗? - Michael
我可以问一个愚蠢的问题吗:如果有一种情况,你必须创建并运行 QThread ,为什么要费力检测你的代码当前是在 QThread 还是其他(非 Qt)事件循环中运行?如果可以创建 QThread,无论当前运行的事件循环类型如何,都应该创建它。 - Oleg Andriyanov
显示剩余2条评论
3个回答

8

回答关于Qt 5的问题。

您可以通过调用静态函数QThread::CurrentThread来获取当前的QThread。实践证明,即使在程序中没有QApplication实例,它也会返回非空指针。

接下来要做的是调用QThread::eventDispatcher函数。如果当前线程中没有Qt事件循环,则返回NULL。不幸的是,这个函数仅在Qt 5及以上版本中可用。希望在早期版本中有其他方法来获取所需信息。

顺便说一句,我建议您无论您的代码是否在Qt或任何其他事件循环中运行,都应该启动QThread。如果有需要始终生成QThread的情况,我更喜欢始终生成它。代码越少,错误就越少。

更新:在Qt 4中,您可以使用:

QAbstractEventDispatcher::instance()

请查看文档

这回答了问题。由于我现在被困在Qt 4.7中,我会采纳你的建议并始终创建QThread。 - Matthew
@matthewmyers 无论如何都已更新为Qt4。你可以进行试验。 - Oleg Andriyanov
我想知道是否有线程安全的方法可以等待(例如等待某个线程进入事件循环)。 - Swift - Friday Pie
Qt 5.15.2,创建了一个没有事件循环的QThread(通过覆盖run方法;同时调用堆栈确认在那里没有事件循环时)--但是eventDispatcher()仍然返回非空指针到某个QEventDispatcherWin32实例:( - Taras

2
int QThread::loopLevel() const

返回线程的当前事件循环级别。 注意:只能在该线程本身内部调用,即当它是当前线程时。 此函数在Qt 5.5中引入。


0

来自QThread文档

一个QThread对象在程序中管理一个控制线程。 QThreads从run()开始执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。

因此,当您调用run时,它具有一个事件循环。


3
他在询问线程相关的问题,据我理解,并非关于应用程序的问题。 - Oleg Andriyanov
3
这也不正确。你可以在没有事件循环的情况下运行。 - dtech
1
@Michael - 你可以重载QThread并在最后不调用exec来实现run方法,这样你就会得到一个没有运行事件循环的线程实例。 - dtech
1
谢谢大家,我知道QThread会启动一个事件循环,在我的类运行时,它可能不在QThread中,因此我必须启动一个QThread来获取事件循环。 - Matthew
1
默认情况下并不意味着总是如此,有许多用例需要线程但不需要事件循环。这是完全合法的用法。如果您重载 QThread 并实现了 run 方法,则只有在需要时才启动事件循环。 - dtech
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接