如何处理“内部C++对象(某些对象)已删除”?

问题描述 投票:0回答:1

当我关闭具有记录器的窗口,然后重新打开该窗口时,我收到“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()

python pyqt pyside
1个回答
0
投票

正如评论所建议的,创建一个在窗口关闭时发出的自定义信号解决了问题。 (如何创建自定义信号: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()
© www.soinside.com 2019 - 2024. All rights reserved.