亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PyQt5:同一窗口的多個實例

PyQt5:同一窗口的多個實例

當年話下 2022-08-25 14:06:54
我在使用 pyqt5 時遇到問題。我有這段代碼來實例化我的類并打開我的窗口,而無需在 show 方法之后關閉(因為 gc)。def user_crud():  global crud  crud = TCrudUsuario()  crud.show()它工作得很好,但是在TCrudUsuario類上,我有一些按鈕連接到帶有參數的方法,所以我使用的是lambda(嘗試部分,但發生同樣的問題),如下所示:self.btnNovo.clicked.connect(lambda: self.manage_user(1))問題是:如果我使用lambda或部分連接到我的方法manage_user(),它允許我打開TCrudUsuario類的多個實例,打開兩個或多個窗口。但是,如果我刪除連接方法,它只會打開1個窗口。我的目標是只允許一個實例/一個窗口。有誰知道為什么會發生這種情況?可重現代碼:from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_test(QtWidgets.QMainWindow):    def __init__(self):        super().__init__()        self.setObjectName("test")        self.resize(380, 250)        self.btntest = QtWidgets.QPushButton(self)        self.btntest.setGeometry(QtCore.QRect(70, 190, 100, 40))        self.btntest.setText('open other window')        self.btntest.clicked.connect(open_otherwindow)class OtherWindow(QtWidgets.QMainWindow):    def __init__(self):        super().__init__()        self.setObjectName("otherwindow")        self.resize(250, 250)        self.button = QtWidgets.QPushButton(self)        self.button.setGeometry(QtCore.QRect(70, 100, 100, 40))        self.button.setText('hello')        self.button.clicked.connect(lambda: self.nothing(1))    def nothing(self, arg):        passdef open_otherwindow():    global w    w = OtherWindow()    w.show()if __name__ == "__main__":    import sys    app = QtWidgets.QApplication(sys.argv)    app.setStyle('Fusion')    test = Ui_test()    test.show()    sys.exit(app.exec_())
查看完整描述

1 回答

?
紫衣仙女

TA貢獻1839條經驗 獲得超15個贊

解釋:

要了解問題,必須分析以下 2 個代碼及其輸出:


示例1


from PyQt5 import QtCore



if __name__ == "__main__":

    app = QtCore.QCoreApplication([])


    o = QtCore.QObject()

    o.destroyed.connect(lambda: print("destroyed o"))


    o = QtCore.QObject()


    def on_timeout():

        print("quit")

        QtCore.QCoreApplication.quit()


    QtCore.QTimer.singleShot(1000, on_timeout)


    app.exec_()

destroyed o

quit

示例 2


from PyQt5 import QtCore



if __name__ == "__main__":

    app = QtCore.QCoreApplication([])


    o = QtCore.QObject()

    o.destroyed.connect(lambda: print("destroyed o"))


    p = o


    o = QtCore.QObject()


    def on_timeout():

        print("quit")

        QtCore.QCoreApplication.quit()


    QtCore.QTimer.singleShot(1000, on_timeout)


    app.exec_()

quit

destroyed o

在第一個示例中,變量“o”被分配了一個QObject,當另一個QObject被分配時,初始QObject被刪除,因此在“退出”之前打印“銷毀”。


在第二個示例中,它具有差異“p = o”,其中引用QObject,也就是說,在該行中“p”和“o”表示相同的對象,因此通過分配“或”一個新的QObject,初始QObject不會被破壞,并且只有在循環結束時并且GC完成其工作時才被銷毀。


這就是在你的情況下以一種微妙的方式發生的事情,“p = o”的邏輯是QObject存儲在另一個“地方”,而在你的例子中,“地方”是具有自己作用域的lambda(類似于部分)。具體來說,在您的示例中,創建了一個新窗口,銷毀了前一個窗口,從而導致始終顯示單個窗口。


溶液:

一種可能的解決方案是防止刪除第一個窗口并使用標志創建新窗口:


from PyQt5 import QtCore, QtGui, QtWidgets


flag = False


# ...


def open_otherwindow():

    global w, flag

    if not flag:

        w = OtherWindow()

        w.show()

    flag = True


# ...


查看完整回答
反對 回復 2022-08-25
  • 1 回答
  • 0 關注
  • 253 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號