簡體   English   中英

關閉 window(不是子窗口)后執行 function?

[英]Execute a function after closing a window (not a child window)?

我在我的應用程序中有一個按鈕,點擊后會打開另一個 window (這是一個單獨的 python 文件)。

我想在第二個 window 關閉后執行 function 。 有沒有辦法可以捕獲該窗口的“關閉”信號或類似的東西?

這是我的代碼:(主窗口)

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore    import Qt
from PyQt5.QtGui     import QPainter, QColor
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtWidgets import QPushButton
import second_dialog  # the second window I am importing

from sys import exit as sysExit

class Marker(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.resize(350, 250)
        self.openbtn = QPushButton('open')
        self.openbtn.clicked.connect(self.open_dialog)
        self.label_1 = QtWidgets.QLabel()
        self.label_1.setGeometry(QtCore.QRect(10, 20, 150, 31))
        self.label_1.setObjectName("label_1")
        self.label_1.setText("HEy")

        HBox = QHBoxLayout()
        HBox.addWidget(self.openbtn)
        HBox.addWidget(self.label_1)
        HBox.addStretch(1)

        VBox = QVBoxLayout()
        VBox.addLayout(HBox)
        VBox.addStretch(1)

        self.setLayout(VBox)
      
    def open_dialog(self):
        self.dialog = QtWidgets.QWidget()
        self.box = second_dialog.Marker()
        self.box.show()
        

    def do_something(self):
        self.label_1.setText("Closed")
    
    def paintEvent(self, event):
        p = QPainter(self)
        p.fillRect(self.rect(), QColor(128, 128, 128, 128))
      
if __name__ == "__main__":
    MainEventThred = QApplication([])

    MainApp = Marker()
    MainApp.show()

    MainEventThred.exec()

這是第二個 window 的代碼:

from PyQt5 import QtWidgets
from PyQt5.QtCore    import Qt
from PyQt5.QtGui     import QPainter, QColor
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtWidgets import QPushButton
import first_window

from sys import exit as sysExit

class Marker(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.resize(350, 250)
        self.openbtn = QPushButton('close')
        self.openbtn.clicked.connect(self.Close)

        HBox = QHBoxLayout()
        HBox.addWidget(self.openbtn)
        HBox.addStretch(1)

        VBox = QVBoxLayout()
        VBox.addLayout(HBox)
        VBox.addStretch(1)

        self.setLayout(VBox)
      
    def Close(self):
        TEST_draggable.Marker.do_something(first_window.Marker)
        self.close()
        

    def paintEvent(self, event):
        p = QPainter(self)
        p.fillRect(self.rect(), QColor(128, 128, 128, 128))
      
if __name__ == "__main__":
    MainEventThred = QApplication([])

    MainApp = Marker()
    MainApp.show()

    MainEventThred.exec()

代碼不運行並拋出此錯誤:

Traceback (most recent call last):
  File "some/path/second_dialog.py", line 28, in Close
    TEST_draggable.Marker.do_something(first_window.Marker)
  File "some/path/first_window.py", line 39, in do_something
    self.label_1.setText("clicked")
AttributeError: type object 'Marker' has no attribute 'label_1'
[1]    7552 abort (core dumped)  /usr/local/bin/python3 

我怎樣才能解決這個問題? 我查了很多論壇懷疑循環進口是罪魁禍首,但我不確定。 請幫忙。

該問題與導入無關,而是因為您嘗試在class上運行實例方法。

“罪魁禍首”在這里:

TEST_draggable.Marker.do_something(first_window.Marker)

first_window.Marker將用於do_something中的self參數,但由於它是 class,它沒有label_1屬性(只有該 class 的實例具有該屬性)。 我建議您對類和實例的一般工作方式以及如何在 Python 中處理它們進行一些研究。

最簡單的解決方案是為第二個 window 創建自己的信號,並將該信號連接到 function 上,該信號將“do_something”。 然后,我們沒有連接到新的 function,而是將closeEvent()子類化並從那里發送信號,這樣即使用戶單擊標題欄上的專用按鈕,我們也可以捕獲關閉。 請注意,如果您想更改close的行為,您可以覆蓋它,然后調用基本實現( super().close() )而不是使用另一個 function 名稱(順便說一下,它不應該有大寫的名稱,因為它們應該只用於類和常量)。

這是第二個class; 請注意,為不同的類使用相同的名稱是一個非常糟糕的主意。

from PyQt5.QtCore import pyqtSignal

class Marker(QWidget):
    closed = pyqtSignal()
    def __init__(self):
        QWidget.__init__(self)
        self.resize(350, 250)
        self.openbtn = QPushButton('close')
        self.openbtn.clicked.connect(self.close)
        # ...

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

然后,在第一個:

class Marker(QWidget):
    # ...
    def open_dialog(self):
        self.dialog = QtWidgets.QWidget()
        self.box = second_dialog.Marker()
        self.box.closed.connect(self.do_something)
        self.box.show()

暫無
暫無

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

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