例如:
#!/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()函数。
我正在制作一个只使用qt显示一些不需要用户交互的内容的脚本,所以我更希望gui代码在后台运行。
答案 0 :(得分:2)
这是不可能的。 Qt documentation州:
虽然
QObject
是可重入的,但GUI类(尤其是QWidget
及其所有子类)不可重入。它们只能在主线程中使用。如前所述,还必须从该主题调用QCoreApplication::exec()
。
(强调我的)
另一方面,This answer建议实际上这不是真的:)但似乎PySide坚持官方版本:
这可以通过以下代码示例进行验证:
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
的选项 - 它可以工作,但在退出时崩溃。
因此,解决方案似乎让Qt拥有主线程,并在单独的线程中组织您的处理。这不应该是一个问题:如果你能够很好地区分你的问题,那么你的控制台应用程序部分对它运行的线程没有任何影响。
答案 1 :(得分:1)
我不确定PySide是否会施加任何限制,但这里是用C ++完成的:
是的,Qt文档目前说只允许主线程。但是,the Qt source code中没有任何内容禁止在辅助线程中创建QApplication,然后在该线程中使用GUI类(对于Windows和Linux)。文档应该更改。
Mac OS X虽然不同 - 但Cocoa框架只允许主线程中的GUI操作。