如何阻止qt应用程序冻结主程序? [英] How to stop qt app from freezing the main program?

查看:86
本文介绍了如何阻止qt应用程序冻结主程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如:

#!/usr/bin/env python3

import sys
from PySide import QtCore, QtGui

class Dialog(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        button = QtGui.QPushButton("test")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(button)
        self.setLayout(layout)

app = QtGui.QApplication(sys.argv)
toast = Dialog()
toast.show()
app.exec_()
print("App freezes the main process!")

在您关闭对话框之前,不会执行最后一个 print() 函数.

The last print() function will not be executed until you close the dialog.

我正在编写一个脚本,它只使用 qt 来显示一些不需要用户交互的内容,所以我更喜欢 gui 代码在后台运行.

I am working on a script that only uses qt for displaying some content that does not require user interaction, so I would prefer the gui code runs in background.

推荐答案

这是不可能的.Qt 文档 指出:

This is not possible. Qt documentation states:

尽管 QObject 是可重入的,但 GUI 类,特别是 QWidget 及其所有子类,是不可重入的.它们只能在主线程中使用.如前所述,还必须从那个线程调用QCoreApplication::exec().

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.

(强调我的)

这个答案另一方面表明,实际上这不是真的:)但是似乎 PySide 坚持正式版:

This answer suggests on the other hand that in reality this is not true :) However it seems that PySide sticks to the official version:

这可以通过以下代码示例进行验证:

This can be verified by the following code sample:

import sys
import threading
from PySide import QtCore, QtGui

class Dialog(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        button = QtGui.QPushButton("test")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(button)
        self.setLayout(layout)

app = QtGui.QApplication(sys.argv)
toast = Dialog()
toast.show()

t = threading.Thread(target = lambda: app.exec_())
t.daemon = True
t.start()
print("App freezes the main process!")
input()

产生以下输出:

App freezes the main process!
QApplication::exec: Must be called from the main thread

(以及崩溃,在我的机器上).我还通过在另一个线程中创建 app 验证了该选项 - 它可以工作,但在退出时崩溃.

(and a crash, on my machine). I have also verified the option with creating the app within the other thread - it works, but crashes on exit.

所以解决方案似乎让 Qt 拥有主线程,并在单独的线程中组织您的处理.这应该不是问题:如果你能很好地分离你的关注点,它不会对你的控制台应用部分在哪个线程上运行产生影响.

So the solution seems to let Qt have the main thread, and organize your processing in a separate thread. This shouldn't really be a problem: if you'll separate your concerns well it won't make a difference for your console-app part on which thread it's running.

这篇关于如何阻止qt应用程序冻结主程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆