Pyside / Pyqt从窗口打开新窗口(事件循环已在运行)

时间:2017-07-06 19:30:57

标签: python pyqt pyqt4 pyside qeventloop

我正在尝试创建一个用作启动所有其他已创建工具的集线器的UI。问题是,如果我尝试从toolshub UI启动UI,它将不会让我,因为事件循环已经在运行。我知道在启动新窗口时我无法执行此APP = QtGui.QApplication(sys.argv)和APP.exec_(),因为当我为toolshub 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()

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

由于

1 个答案:

答案 0 :(得分:0)

应该只有一个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()

<强> main.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()