当我关闭具有记录器的窗口,然后重新打开该窗口时,我收到“RuntimeError:内部 C++ 对象(PySide6.QtWidgets.QPlainTextEdit)已删除。”(我根据这篇文章制作了记录器:Best在pyqt中显示日志的方法?)。
当我从 LoggerWindow 的 closeEvent 中删除“self.deleteLater()”时,我没有收到错误,因为 QWidget 没有被删除。但问题是,在我的程序中,我需要“self.deleteLater()”来检测窗口是否已关闭(使用 self.(QWidget).destroyed.connect())。
有什么方法可以避免此错误,或者是否有不同的方法来检测窗口何时关闭?
这是我第一次使用日志记录,所以我可能做错了什么。
from PySide6.QtWidgets import QApplication, QWidget, QPlainTextEdit, QVBoxLayout, QPushButton
import os
import logging
import sys
class QTextEditLogger(logging.Handler):
def __init__(self, parent):
super().__init__()
self.widget = QPlainTextEdit(parent)
self.widget.setReadOnly(True)
def emit(self, record):
msg = self.format(record)
self.widget.appendPlainText(msg)
class LoggerWindow(QWidget):
parent_dir = os.getcwd()
def __init__(self):
super().__init__()
self.logger_text_edit = QTextEditLogger(self)
self.logger_text_edit.setFormatter(logging.Formatter('[%(asctime)s %(levelname)s]: %(message)s'))
logging.getLogger().addHandler(self.logger_text_edit)
logging.getLogger().setLevel(logging.DEBUG)
logging.info("Initialized")
main_v_layout = QVBoxLayout()
main_v_layout.addWidget(self.logger_text_edit.widget)
self.setLayout(main_v_layout)
def closeEvent(self, event):
self.deleteLater()
class MainWindow(QWidget):
def __init__(self, app):
super().__init__()
main_v_layout = QVBoxLayout()
button = QPushButton("Push!")
main_v_layout.addWidget(button)
self.setLayout(main_v_layout)
button.clicked.connect(self.button_clicked)
def button_clicked(self):
self.logger_window = LoggerWindow()
self.logger_window.show()
app = QApplication(sys.argv)
window = MainWindow(app)
window.show()
app.exec()
正如评论所建议的,创建一个在窗口关闭时发出的自定义信号解决了问题。 (如何创建自定义信号:PyQt5 - 检测其他窗口何时关闭)
from PySide6.QtWidgets import QApplication, QWidget, QPlainTextEdit, QVBoxLayout, QPushButton
from PySide6.QtCore import Signal
import os
import logging
import sys
class QTextEditLogger(logging.Handler):
def __init__(self, parent):
super().__init__()
self.widget = QPlainTextEdit(parent)
self.widget.setReadOnly(True)
def emit(self, record):
msg = self.format(record)
self.widget.appendPlainText(msg)
class LoggerWindow(QWidget):
signal = Signal()
parent_dir = os.getcwd()
def __init__(self):
super().__init__()
self.logger_text_edit = QTextEditLogger(self)
self.logger_text_edit.setFormatter(logging.Formatter('[%(asctime)s %(levelname)s]: %(message)s'))
logging.getLogger().addHandler(self.logger_text_edit)
logging.getLogger().setLevel(logging.DEBUG)
logging.info("Initialized")
main_v_layout = QVBoxLayout()
main_v_layout.addWidget(self.logger_text_edit.widget)
self.setLayout(main_v_layout)
def closeEvent(self, event):
self.signal.emit()
class MainWindow(QWidget):
def __init__(self, app):
super().__init__()
self.app = app
main_v_layout = QVBoxLayout()
self.button = QPushButton("Push!")
main_v_layout.addWidget(self.button)
self.setLayout(main_v_layout)
self.button.clicked.connect(self.button_clicked)
def button_clicked(self):
self.logger_window = LoggerWindow()
self.logger_window.show()
self.logger_window.signal.connect(self.button.setText("Push Again"))
app = QApplication(sys.argv)
window = MainWindow(app)
window.show()
app.exec()