主线程繁忙时如何使Qt工作?

Bas*_*evs 24 qt multithreading

Main(函数main在那里)我的程序的线程保留用于非GUI任务.它调用了许多冗长的计算功能.所有已实现的GUI都在一个单独的线程中完成它们的工作.

我现在要使用Qt实现一个GUI.Qt文档说所有GUI相关的任务都应该在主线程中完成.在我的例子中,在主线程中偶尔插入QCoreApplication :: processEvents()调用几乎没用,因为它们之间有很大的延迟.

有没有办法克服Qt的这种约束?是不可能在Qt程序的主线程中做一些非GUI相关的事情?

Tho*_*omi 23

不,你应该在一个单独的线程中进行计算.正如您已经提到的,有一个可用的解决方案QCoreApplication::processEvents(),但听起来您无法为您工作.

如果您不想完成设置QThread和移动所有代码的所有工作,您可能会发现QtConcurrent :: run函数很有用 - 它允许您异步运行函数.

一些指示:您应该尝试使主(GUI)线程尽可能轻.大量的IO或计算应该使用QtConcurrent :: run异步完成,或者在单独的QThread中运行.根据代码的复杂程度,您可以使用QtConcurrent方法.

  • 这取决于您正在做什么以及您的计划的结构.如果您需要一个必须始终运行的永久线程,请使用QThread.如果您需要运行许多小的(通常是独立的)任务,并且您不关心在哪个时间运行哪些任务,那么请使用Q​​tConcurrent. (2认同)

tim*_*day 7

最好将长计算卸载到其他线程上,以便主 GUI 线程保持响应。老式的单处理方式是确保您的计算不会在不轮询 GUI 事件处理程序的情况下运行太长时间,但这不会扩展到多核。

幸运的是 Qt 具有出色的线程支持。在过去,你就得滚你,自己的系统,例如使用外包出去的任务的线程池QThreadQMutexQWaitCondition等,但最近发布的Qt做出的事情与更高层次的抽象,如更容易QThreadPoolQtConcurrent::runQFuture


use*_*925 1

Qt 文档中没有明确定义主线程的概念。实际上,进程的主线程(执行 Process.run 函数的进程)可以与主 Qt 线程(像 QApplication 一样实例化第一个 Qt 对象的线程)不同,尽管两个“主”线程通常是同一个。

有效代码结构示例:

下面的函数将在进程“非主线程”thread-1”中运行,它将立即成为Qt的主线程。

def startThread1():      
    app = QApplication(sys.argv)
    app.exec_()  # enter event loop
Run Code Online (Sandbox Code Playgroud)

下面的代码在进程的主线程中运行,不要与进程的主 Qt 和唯一的 GUI 线程混淆。

thread1 = Thread(target=self.startThread1)
thread1.start()
input('I am busy until you press enter')
Run Code Online (Sandbox Code Playgroud)