【问题标题】:Pyside / Pyqt Opening new windows from a window (Event loop is already running)Pyside / Pyqt 从窗口打开新窗口(事件循环已在运行)
【发布时间】:2017-12-10 23:04:31
【问题描述】:

我正在尝试创建一个 UI,它将充当启动所有其他已创建工具的中心。问题是,如果我尝试从工具集 UI 启动 UI,它不会让我因为事件循环已经在运行。我知道在启动新窗口时我不能执行此 APP = QtGui.QApplication(sys.argv) 和 APP.exec_() ,因为当我为工具集 UI 执行此操作时事件循环已经在运行。但我不知道如何以另一种方式做到这一点。

这是其中一种工具的示例代码,可自行启动。

global APP
APP = None

class toolwindow(QtGui.QDialog):

    def __init__(self, parent=None):
        init_app()
        super(toolwindow, self).__init__(parent)
        self.setWindowTitle('tool')
        self.setMinimumSize(QtCore.QSize(500, 600))
        self.setMaximumSize(QtCore.QSize(500, 600))
        self.create_ui()

    def create_ui(self):
        code goes here

    def closeEvent(self, event):
        QtGui.QDialog.closeEvent(self, event)
        return

def init_app():
    global APP
    APP = QtGui.QApplication.instance()
    if not APP:
        APP = QtGui.QApplication(sys.argv)
    return

def start_ui():
    win= toolwindow()
    win.show()
    APP.exec_()

if __name__ == '__main__':
    start_ui()
global APP
APP = None

现在这里是toolshub ui的代码。这些都是单独的脚本。在 toolshub 中,我正在导入上面的工具。

import tool
LOGGER = logging.getLogger(__name__)
global APP
APP = None

class toolsHub(QtGui.QDialog):

    def __init__(self, parent=None):
        init_app()
        super(toolsHub, self).__init__(parent)
        self.setWindowTitle('Tools Launcher')
        self.setSizeGripEnabled(False)
        self.setMinimumSize(QtCore.QSize(300, 200))
        self.setMaximumSize(QtCore.QSize(300, 200))
        self.create_layouts()

    def create_layouts(self):
        master_layout = QtGui.QVBoxLayout()
        self.setLayout(master_layout)
        self.input_widgets()
        grid_layout = QtGui.QGridLayout()
        grid_layout.addWidget(self.env_creator, 0, 0)
        grid_layout.addWidget(self.p4dl, 1, 0)
        master_layout.addLayout(grid_layout)

    def input_widgets(self):
        self.tool_button= QtGui.QPushButton('launch tool')
        self.tool_button.clicked.connect(self.launch_tool)

    def launch_tool(self):
        tool.start_ui()

    def closeEvent(self, event):
        QtGui.QDialog.closeEvent(self, event)
        return


def init_app():
    global APP
    APP = QtGui.QApplication.instance()
    if not APP:
        APP = QtGui.QApplication(sys.argv)
    return

def start_ui():
    toolui = toolsHub()
    toolui.show()
    APP.exec_()

if __name__ == '__main__':
    start_ui()

那么如何编写和构建这些,以便我可以从工具集 UI 打开工具 UI?我猜我必须更改的代码是工具 UI,我知道我必须取出 APP = QtGui.QApplication(sys.argv) 和 APP.exec_(),但不知道如何启动它。

谢谢

【问题讨论】:

    标签: python pyqt pyqt4 pyside qeventloop


    【解决方案1】:

    应该只有一个 QApplication 实例,并且应该在创建任何小部件之前创建它,因此无需在每个模块中实例化它。

    为了让 QDialog 正确显示,您必须执行它的exec_()

    tool.py:

    [...]
    def start_ui():
        win= toolwindow()
        win.exec_()
    

    完整代码:

    tool.py

    from PySide import QtGui, QtCore
    
    APP = None
    
    class toolwindow(QtGui.QDialog):
    
        def __init__(self, parent=None):
            init_app()
            super(toolwindow, self).__init__(parent)
            self.setWindowTitle('tool')
            self.setMinimumSize(QtCore.QSize(500, 600))
            self.setMaximumSize(QtCore.QSize(500, 600))
            self.create_ui()
    
        def create_ui(self):
            pass
        def closeEvent(self, event):
            QtGui.QDialog.closeEvent(self, event)
            return
    
    def init_app():
        global APP
        APP = QtGui.QApplication.instance()
        if not APP:
            APP = QtGui.QApplication(sys.argv)
        return
    
    def start_ui():
        win= toolwindow()
        win.exec_()
    
    if __name__ == '__main__':
        start_ui()
    

    ma​​in.py

    from PySide import QtGui, QtCore
    import tool
    import logging
    import sys
    
    LOGGER = logging.getLogger(__name__)
    APP = None
    
    class toolsHub(QtGui.QDialog):
    
        def __init__(self, parent=None):
            init_app()
            super(toolsHub, self).__init__(parent)
            self.setWindowTitle('Tools Launcher')
            self.setSizeGripEnabled(False)
            self.setMinimumSize(QtCore.QSize(300, 200))
            self.setMaximumSize(QtCore.QSize(300, 200))
            self.create_layouts()
    
        def create_layouts(self):
            master_layout = QtGui.QVBoxLayout()
            self.setLayout(master_layout)
            self.input_widgets()
            grid_layout = QtGui.QGridLayout()
            grid_layout.addWidget(QtGui.QPushButton(), 0, 0)
            grid_layout.addWidget(QtGui.QPushButton(), 1, 0)
            master_layout.addLayout(grid_layout)
    
        def input_widgets(self):
            self.tool_button= QtGui.QPushButton('launch tool')
            self.tool_button.clicked.connect(self.launch_tool)
            self.layout().addWidget(self.tool_button)
    
        def launch_tool(self):
            tool.start_ui()
    
        def closeEvent(self, event):
            QtGui.QDialog.closeEvent(self, event)
    
    
    def init_app():
        global APP
        APP = QtGui.QApplication.instance()
        if not APP:
            APP = QtGui.QApplication(sys.argv)
        return
    
    def start_ui():
        toolui = toolsHub()
        toolui.show()
        APP.exec_()
    
    if __name__ == '__main__':
        start_ui()
    

    【讨论】:

    • 太棒了!所以我应该将 init_app 模块留在 tool.py 中,它设置 APP = QtGui.QApplication(sys.argv)?如果我把它拿出来它仍然有效,所以我似乎不需要它。仅适用于 main.py ??
    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2018-12-25
    • 2022-07-02
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    相关资源
    最近更新 更多