簡體   English   中英

如何在不退出python腳本的情況下銷毀一個QApplication然后運行一個新的?

[英]How to destroy a QApplication and then run a new one without exiting the python script?

我想創建一個 QApplication,然后使用鍵盤快捷鍵退出。 然后python腳本應該調用另一個QApplication。

我目前的問題是當第二個 QApplication 即將運行時出現此錯誤:

app2 = QApplication()
RuntimeError: Please destroy the QApplication singleton before creating a new QApplication instance.

我有以下結構:

| main.py
| Q1.py
| Q2.py

這是 main.py:

import Q1 as record
import Q2 as display

def main():
    record.main()
    display.main()


if __name__ == "__main__":
    main()

這是造成問題的 Q1:

import sys
from PySide2 import QtWidgets as qtw
from PySide2 import QtGui as qtg
from PySide2 import QtCore as qtc
from PySide2 import QtMultimedia as qtmm


class MainWindow(qtw.QMainWindow):
    def __init__(self):
        super().__init__()

        #Create Window layout with a sound widget
        soundboard = qtw.QWidget()
        soundboard.setLayout(qtw.QGridLayout())
        self.setCentralWidget(soundboard)
        sw = SoundWidget()
        soundboard.layout().addWidget(sw)

        #Window Dimensions
        self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.MinimumExpanding)

        # Code ends here
        self.show()


class SendOrderButton(qtw.QPushButton):
    button_stylesheet = 'background-color: blue; color: white;'

    def __init__(self):
        super().__init__('Send Order')
        self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.Expanding)
        self.setStyleSheet(self.button_stylesheet)
        #self.clicked.connect(qtc.QCoreApplication.instance().quit)

    def press_button(self):
        if self.isEnabled():
            self.setEnabled(False)
            self.setText('Send Order')
        else:
            self.setEnabled(True)
            self.setText('Sent')

class SoundWidget(qtw.QWidget):
    def __init__(self):
        super().__init__()
        self.setLayout(qtw.QGridLayout())

        #Send Order Button
        self.sendorder_button = SendOrderButton()
        self.sendorder_button.setShortcut(qtg.QKeySequence('Tab'))
        self.layout().addWidget(self.sendorder_button, 5, 0, 1, 2)
        self.sendorder_button.clicked.connect(qtc.QCoreApplication.instance().quit)

def main():
    app = qtw.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

這是 Q2.py,它有第二個 QApplication:

import sys
from PySide2.QtCore import (QAbstractTableModel, Slot)
from PySide2.QtWidgets import (QAction, QApplication, QMainWindow,QWidget)

class MainWindow(QMainWindow):
    def __init__(self, widget):
        QMainWindow.__init__(self)

        # Exit QAction
        exit_action = QAction("Exit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.exit_app)

    @Slot()
    def exit_app(self, checked):
        sys.exit()

class CustomTableModel(QAbstractTableModel):
    def __init__(self, data=None):
        QAbstractTableModel.__init__(self)

class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        # Getting the Model
        self.model = CustomTableModel()

def main():
    app2 = QApplication()
    widget = Widget()
    window2 = MainWindow(widget)
    window2.show()
    sys.exit(app2.exec_())

if __name__ == "__main__":
    app = QApplication()
    widget = Widget()
    window = MainWindow(widget)
    window.show()
    sys.exit(app.exec_())

正如評論中所指出的,Qt 應用程序只能並且應該有一個 QApplication(您可能不遵循此規則,但不能保證它正常工作),因此您必須重新構建代碼。

假設您希望首先打開 Q1 窗口,並且當該窗口關閉時,Q2 窗口會打開,這並不意味着您必須在任何時候使用多個 QApplication。 這個想法是知道窗口何時關閉並收到通知,要知道窗口何時關閉,您必須覆蓋窗口的 closeEvent 方法並發出通知,您必須發送信號。

綜上所述,解決方法是:

├── main.py
├── Q1.py
└── Q2.py

主文件

import sys

from PySide2 import QtWidgets as qtw

import Q1 as record
import Q2 as display


def main():
    app = qtw.QApplication(sys.argv)

    w1 = record.get_mainwindow()
    w2 = display.get_mainwindow()

    w1.closed.connect(w2.show)

    w1.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Q1.py

from PySide2 import QtWidgets as qtw
from PySide2 import QtGui as qtg
from PySide2 import QtCore as qtc


class MainWindow(qtw.QMainWindow):
    closed = qtc.Signal()

    def __init__(self):
        super().__init__()

        # Create Window layout with a sound widget
        soundboard = qtw.QWidget()
        soundboard.setLayout(qtw.QGridLayout())
        self.setCentralWidget(soundboard)
        sw = SoundWidget()
        soundboard.layout().addWidget(sw)
        # Window Dimensions
        self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.MinimumExpanding)

        sw.sendorder_button.clicked.connect(self.close)

    def closeEvent(self, event):
        self.closed.emit()
        super().closeEvent(event)


class SendOrderButton(qtw.QPushButton):
    button_stylesheet = "background-color: blue; color: white;"

    def __init__(self):
        super().__init__("Send Order")
        self.setSizePolicy(qtw.QSizePolicy.Expanding, qtw.QSizePolicy.Expanding)
        self.setStyleSheet(self.button_stylesheet)

    def press_button(self):
        if self.isEnabled():
            self.setEnabled(False)
            self.setText("Send Order")
        else:
            self.setEnabled(True)
            self.setText("Sent")


class SoundWidget(qtw.QWidget):
    def __init__(self):
        super().__init__()
        self.setLayout(qtw.QGridLayout())

        # Send Order Button
        self.sendorder_button = SendOrderButton()
        self.sendorder_button.setShortcut(qtg.QKeySequence("Tab"))
        self.layout().addWidget(self.sendorder_button, 5, 0, 1, 2)


def get_mainwindow():
    window = MainWindow()
    return window


if __name__ == "__main__":
    import sys

    app = qtw.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Q2.py

from PySide2 import QtCore as qtc
from PySide2 import QtWidgets as qtw


class MainWindow(qtw.QMainWindow):
    def __init__(self, widget):
        super().__init__()

        file_menu = self.menuBar().addMenu("&File")

        # Exit QAction
        exit_action = qtw.QAction("Exit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.close)

        file_menu.addAction(exit_action)


class CustomTableModel(qtc.QAbstractTableModel):
    pass


class Widget(qtw.QWidget):
    def __init__(self):
        super().__init__()

        # Getting the Model
        self.model = CustomTableModel()


def get_mainwindow():
    widget = Widget()
    window2 = MainWindow(widget)
    return window2


if __name__ == "__main__":
    import sys

    app = qtw.QApplication()
    widget = Widget()
    window = MainWindow(widget)
    window.show()
    sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM