天天看點

PyQt5 多視窗應用中遇到的問題解決(父視窗與子視窗)

問題1:通過點選Button打開新視窗後,如何實作不關閉新視窗的情況下再點選Button時不會建立視窗,而是顯示先前打開的視窗?(以前用tkinter時遇到這個問題,是使用一個boolean值來做開關,如果對象已建立,就不建立,否則建立,然後關閉視窗時在控制該boolean,該方法可行但是比較麻煩)

分析:有兩種方法:

1.建立視窗時使用exec_()函數(顯示一個模式對話框,并且鎖住程式直到使用者關閉該對話框為止,函數傳回一個DialogCode結果;在對話框彈出期間,使用者不可以切換同程式下的其它視窗,直到該對話框被關閉)。

但是我需要user在通過Button打開該視窗的同時,可以對父視窗進行操作,是以不使用exec_()函數

2.使用show()函數建立視窗(顯示一個非模式對話框。控制權即刻傳回給調用函數。彈出視窗是否模式對話框,取決于modal屬性的值。)

使用show()建立的子視窗在打開時可以操作父視窗。此處,建立視窗有兩種方法:

(1)在槽函數中執行個體化視窗,然後.show()建立視窗:

class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.pushButton_1.clicked.connect(self.openGenWin)
        
    def closeEvent(self, event):
        self.genWin.close()
        event.accept()

    # 在槽函數openGenWin中執行個體化并調用show()
    def openGenWin(self):
        self.genWin = MyGeneratorWindow()
        self.genWin.show()
           

點選Button後,子視窗正常打開,重複點選按鈕,子視窗重複彈出

(2)在__init__()方法中執行個體化視窗,在槽函數中調用show()

class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.pushButton_1.clicked.connect(self.openGenWin)
        # 在構造方法中執行個體化視窗
        self.genWin = MyGeneratorWindow()

    def closeEvent(self, event):
        self.genWin.close()
        event.accept()
    
    # 在槽函數中調用show()
    def openGenWin(self):
        self.genWin.show()
           

重複點選Button後,子視窗不重複彈出

結果:使用方法2(2)即解決問題

該問題查閱過下列部落格:

https://blog.csdn.net/chengmo123/article/details/93379470

https://blog.csdn.net/weixin_40520077/article/details/104040414

問題2:PyQt5中目前不知道在父視窗與子視窗都開啟時,如何做到關閉父視窗,子視窗也同時關閉,是以用重寫父視窗的closeEvent(self, event)來解決:

def closeEvent(self, event):
        self.genWin.close()
        event.accept()
           

該方法是PyQt5中點選視窗右上角“X”時觸發的函數

event參數:如果調用event.ignore()方法,則會使關閉視窗失效

                    如果調用event.accept()方法,則會關閉視窗

結果:要實作在關閉父視窗時子視窗同時關閉,則在重寫該方法時,在event.accept()之前調用close()方法關閉子視窗。