首页 > 解决方案 > 如何在 Python 中并行运行两个 GUI?

问题描述

我们正在谈论 python 2.7 和 PyQt4。

我正在使用一个名为 PyCorder 的用于脑电图分析的开源程序,它从系统电极放大器接收数据并将它们绘制在 GUI 中;出于这个问题的目的,我们可以将其视为一个黑匣子。我用 Qt 设计器实现了一个简单的界面。我的目标是同时运行 PyCorder 和我的界面,以便它们可以在它们之间交换数据。

这是我的界面启动的代码行:


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我想这对于使用 Qt 设计器完成的任何界面都很常见。接下来是 PyCorder 启动部分:


def main(args):

    print "Starting PyCorder, please wait ...\n"
    setpriority(priority=4)
    app = Qt.QApplication(args)
    try:
        win = None
        win = MainWindow()
        win.showMaximized()
        if ShowConfirmationDialog:
            accept = Qt.QMessageBox.warning(None, "PyCorder Disclaimer", ConfirmationText, 
                                            "Accept", "Cancel", "", 1)
            if accept == 0:
                win.usageConfirmed = True
                app.exec_()
            else:
                win.close()
        else:
            win.usageConfirmed = True
            app.exec_()
    except Exception as e:
        tb = GetExceptionTraceBack()[0]
        Qt.QMessageBox.critical(None, "PyCorder", tb + " -> " + str(e))
        if win != None:
            win.close()

    # show the battery disconnection reminder
    if ShowBatteryReminder and win and win.usageConfirmed:
        DlgBatteryInfo().exec_()

    print "PyCorder terminated\n"


if __name__ == '__main__':
    main(sys.argv)

仅知道各自代码的这两个部分就足以回答我的问题吗?是否有任何工具箱可用于实现我的目标?

标签: pythonpython-2.7parallel-processingpyqtpyqt4

解决方案


有很多方法可以做到这一点,但我更喜欢使用中央“窗口管理器”来充当两个窗口的所有者和相互通信中心。以下是该技术的示例,需要根据您的需要进行调整。请注意,我使用 Qt5。我在 Qt5 上进行了测试,然后尝试在没有测试的情况下转换为 Qt4。它应该是正确的,但可能需要一些调整。

from PyQt4 import QtCore, QtGui

class WindowManager(QtCore.QObject):
    """ 
    Inheriting from QObject has benefits.
    For instance, the WindowManager can not have pyQtSignal members, if needed
    """
    def __init__(self):
        super(WindowManager, self).__init__()
        self.firstWindow = FirstWindow(self)
        self.secondWindow = SecondWindow(self)
        self.firstWindow.show()
        self.secondWindow.show()

class FirstWindow(QtGui.QMainWindow):
    def __init__(self, manager):
        super(FirstWindow, self).__init__()
        self.manager = manager
        self.mainWidget = QtGui.QWidget()
        self.setCentralWidget(self.mainWidget)
        self.mainLayout = QtGui.QVBoxLayout(self.mainWidget)
        self.clickyButton = QtGui.QPushButton("Click me")
        self.mainLayout.addWidget(self.clickyButton)
        self.clickyButton.clicked.connect(self.clickyButtonClicked)
    def clickyButtonClicked(self, checked=None):
        self.manager.secondWindow.setMessage("Clicky button clicked")

class SecondWindow(QtGui.QMainWindow):
    def __init__(self, manager):
        super(SecondWindow, self).__init__()
        self.manager = manager
        self.mainWidget = QtGui.QWidget()
        self.setCentralWidget(self.mainWidget)
        self.mainLayout = QtGui.QVBoxLayout(self.mainWidget)
        self.messageBox = QtGui.QLabel()
        self.mainLayout.addWidget(self.messageBox)
    def setMessage(self, message):
        self.messageBox.setText(message)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    manager = WindowManager()
    sys.exit(app.exec_())

推荐阅读