![](/img/trans.png)
[英]opencv window not closing after calling destroyAllWindows() 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.