我是Qt的新手。我在python中使用带内省的Gtk3和Glade UI设计器构建了一些东西,包括构建我的代码以作为事件发生时运行的函数运行。在GTK中,如果主循环当前没有循环,则UI冻结。
现在,我正在尝试学习PyQt。看起来很奇怪的是我告诉Window显示,并且UI出现,并且Python提示返回。但是GUI并没有像我期望的那样被冻结(因为我没有运行主循环)。
就测试python解释器中的UI内容而言,这非常好。但这怎么可能呢? Qt正在制作另一个循环的东西吗?
以下是代码:
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_multippp(object):
def setupUi(self, multippp):
multippp.setObjectName(_fromUtf8("multippp"))
multippp.resize(371, 43)
self.verticalLayout = QtGui.QVBoxLayout(multippp)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label = QtGui.QLabel(multippp)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.verticalLayout.addLayout(self.verticalLayout_2)
self.retranslateUi(multippp)
QtCore.QMetaObject.connectSlotsByName(multippp)
def retranslateUi(self, multippp):
multippp.setWindowTitle(QtGui.QApplication.translate("multippp", "Multiple PPP Accounts", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("multippp", "More than one PPP account found, please select one:", None, QtGui.QApplication.UnicodeUTF8))
import sys
app = QtGui.QApplication(sys.argv)
multippp = QtGui.QDialog()
ui = Ui_multippp()
ui.setupUi(multippp)
multippp.show()
# At this point the python prompt returns, but the UI is interactive. I can add/remove buttons at the python prompt.
答案 0 :(得分:0)
这可能会有所帮助: http://qt-project.org/doc/qt-5.0/qtcore/threads-qobject.html
“每个线程都有自己的事件循环。初始线程使用QCoreApplication :: exec()启动其事件循环;其他线程可以使用QThread :: exec()启动事件循环。像QCoreApplication,QThread提供了一个exit(int)函数和一个quit()槽。“
答案 1 :(得分:0)
如果您考虑一下,解释器提示符正在运行一个等待您输入的主循环。
PyQt不仅有一个通过运行QCoreApplication._exec()
来启动的主循环,而且它also hooks itself into the interpreter prompt's mainloop(就此而言,是pdb的主循环)。当解释器提示在等待输入的圈子中旋转时,正在处理Qt事件。
例如,使用上面的代码作为起点,如果使解释器主循环需要一段时间返回,您可以看到接口将如何冻结:
from PyQt4 import QtCore, QtGui
import time
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_multippp(object):
def setupUi(self, multippp):
multippp.setObjectName(_fromUtf8("multippp"))
multippp.resize(371, 43)
self.verticalLayout = QtGui.QVBoxLayout(multippp)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label = QtGui.QLabel(multippp)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.verticalLayout.addLayout(self.verticalLayout_2)
self.retranslateUi(multippp)
QtCore.QMetaObject.connectSlotsByName(multippp)
def retranslateUi(self, multippp):
multippp.setWindowTitle(QtGui.QApplication.translate("multippp", "Multiple PPP Accounts", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("multippp", "More than one PPP account found, please select one:", None, QtGui.QApplication.UnicodeUTF8))
import sys
app = QtGui.QApplication(sys.argv)
multippp = QtGui.QDialog()
ui = Ui_multippp()
ui.setupUi(multippp)
multippp.show()
# UI is visible and interactive at this point
# But after the next command, the UI will freeze for 5 seconds while the interpreter loop is 'busy' waiting for the command to return
time.sleep(5)
当您尝试使用pdb进行调试时,会出现一个实际的问题:Qt主循环被挂接到pdb提示符中,这使得当您执行类似{I}时,您尝试重新进入主循环{1}}。您将收到类似“QCoreApplication :: exec:事件循环已在运行”的错误。为了能够使用pdb,您可以将其包装在pdb.set_trace()
和QtCore.pyqtRemoveInputHook()
中,这样可以将Qt与输入循环断开连接,冻结它并让您进行调试。
另见http://www.riverbankcomputing.com/pipermail/pyqt/2007-September/017134.html