0

我对Qt相当陌生。我使用 Gtk3 和 Glade UI 设计器在 python 中构建了一些东西,包括构建我的代码以作为事件发生时运行的函数运行。在 GTK 中,如果主循环当前没有循环,您的 UI 将冻结。

现在,我正在尝试学习 PyQt。看起来很奇怪的是,我告诉 Window 显示,UI 出现,Python 提示返回。但是 GUI 并没有像我对 GTK 所期望的那样冻结(因为我没有运行主循环)。

就从 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.
4

2 回答 2

0

这可能会有所帮助:http: //qt-project.org/doc/qt-5.0/qtcore/threads-qobject.html

"每个线程都可以有自己的事件循环。初始线程使用 QCoreApplication::exec() 启动其事件循环;其他线程可以使用 QThread::exec() 启动事件循环。与 QCoreApplication 一样,QThread 提供了一个 exit(int)函数和一个 quit() 槽。 "

于 2013-05-12T05:57:35.730 回答
0

如果您考虑一下,解释器提示符正在运行一个主循环,等待您的输入。

PyQt 不仅有一个由 running 启动的主循环QCoreApplication._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()andQtCore.pyqtRestoreInputHook()中,这样您就可以断开 Qt 与输入循环的连接,冻结它并让您进行调试。

另见http://www.riverbankcomputing.com/pipermail/pyqt/20​​07-September/017134.html

于 2013-05-21T04:08:56.143 回答