Python 为什么我的PyQt用户界面没有冻结,而我没有';你没有循环吗?
我对Qt是相当陌生的。我已经使用Gtk3和内省以及GladeUI设计器在python中构建了一些东西,包括构建代码以在事件发生时作为函数运行。在GTK中,如果主循环当前没有循环,UI将冻结 现在,我正在努力学习PyQt。奇怪的是,我告诉窗口显示,UI出现,Python提示符返回。但是GUI并不像我对GTK所期望的那样被冻结(因为我没有运行主循环) 就从python解释器测试UI而言,这真的很好。但这怎么可能呢?Qt是否正在生成另一个正在循环的线程 代码如下:Python 为什么我的PyQt用户界面没有冻结,而我没有';你没有循环吗?,python,qt,pyqt,pyqt4,Python,Qt,Pyqt,Pyqt4,我对Qt是相当陌生的。我已经使用Gtk3和内省以及GladeUI设计器在python中构建了一些东西,包括构建代码以在事件发生时作为函数运行。在GTK中,如果主循环当前没有循环,UI将冻结 现在,我正在努力学习PyQt。奇怪的是,我告诉窗口显示,UI出现,Python提示符返回。但是GUI并不像我对GTK所期望的那样被冻结(因为我没有运行主循环) 就从python解释器测试UI而言,这真的很好。但这怎么可能呢?Qt是否正在生成另一个正在循环的线程 代码如下: from PyQt4 import
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.
这可能会有帮助:
“每个线程都可以有自己的事件循环。初始线程使用QCoreApplication::exec()启动其事件循环;其他线程可以使用QThread::exec()启动事件循环。与QCoreApplication一样,QThread提供一个exit(int)函数和一个quit()槽。”,解释器提示符正在运行一个主循环,等待您的输入 PyQt不仅有一个主循环,通过运行
QCoreApplication.\u exec()
,可以启动该循环,而且还有它(就此而言,是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提示符中,这使得您在执行类似于pdb.set_trace()
的操作时尝试重新进入主循环。您将收到类似“QCoreApplication::exec:事件循环已在运行”的错误。为了能够使用pdb,您可以将其包装在QtCore.pyqtRemoveInputHook()
和QtCore.pyqtremoreInputhook()
中,这将允许您断开Qt与输入循环的连接,冻结它并进行调试
另请参见能否发布一些示例代码?