Pyside/Pyqt Открытие новых окон из окна (цикл событий уже запущен)

Я пытаюсь создать пользовательский интерфейс, который будет действовать как центр для запуска всех других созданных инструментов. Проблема в том, что если я попытаюсь запустить пользовательский интерфейс из пользовательского интерфейса toolshub, это не позволит мне, потому что цикл событий уже запущен. Я знаю, что не могу сделать это APP = QtGui.QApplication(sys.argv) и APP.exec_() при запуске нового окна, потому что цикл событий уже запущен, когда я сделал это для пользовательского интерфейса toolshub. Но я не могу понять, как это сделать по-другому.

Вот пример кода одного из инструментов, работает самостоятельно.

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. Это два отдельных скрипта. В 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? Я предполагаю, что код, который я должен изменить, - это пользовательский интерфейс инструмента, я знаю, что мне нужно вынуть APP = QtGui.QApplication(sys.argv) и APP.exec_(), но не знаю, что делать, чтобы запустить его.

Спасибо


person ghost654    schedule 06.07.2017    source источник


Ответы (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()

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()
person eyllanesc    schedule 06.07.2017
comment
Круто что получилось! Так что я должен оставить модуль init_app в tool.py, где он устанавливает APP = QtGui.QApplication(sys.argv)? если я вытащу его, он все еще работает, так что, похоже, мне это не нужно. Только для main.py ?? - person ghost654; 06.07.2017