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

时间:2009-09-06 16:22:47

标签: multithreading qt

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

我现在要使用Qt再实现一个GUI。 Qt documentation表示所有与GUI相关的任务都应该在主线程中完成。 在我的情况下,在主线程中偶尔插入QCoreApplication :: processEvents()调用几乎没用,因为它们之间有很大的延迟。

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

4 个答案:

答案 0 :(得分:21)

不,你应该在一个单独的线程中进行计算。正如您已经提到的那样,QCoreApplication::processEvents()中提供了一种解决方法,但听起来您无法为此工作。

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

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

答案 1 :(得分:4)

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

幸运的是Qt非常出色threading support。在过去,您必须使用QThreadQMutexQWaitCondition等自行推送系统,例如将任务分配到线程池,但最近的Qt版本已经完成使用QThreadPoolQtConcurrent::runQFuture等更高级别的抽象可以更轻松地完成任务。

答案 2 :(得分:0)

如果你从另一个线程调用QApplication :: exec(),我不知道会怎么样,然后它会成为你的gui线程。只是一个想法。

(让我们知道它是否有效,它会很有趣......)

答案 3 :(得分:0)

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

有效代码结构示例:

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

def startThread1():      
    app = QApplication(sys.argv)
    app.exec_()  # enter event loop

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

thread1 = Thread(target=self.startThread1)
thread1.start()
input('I am busy until you press enter')