首页 > 编程问答 >如何处理“内部C++对象(某些对象)已删除”?

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

时间:2024-08-04 15:35:18浏览次数:15  
标签:python pyqt pyside

当我关闭具有记录器的窗口然后重新打开该窗口时,我收到“RuntimeError:内部 C++ 对象 (PySide6.QtWidgets.QPlainTextEdit) 已删除。”(我根据这篇文章制作了记录器: 在 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()


这个错误的发生是因为你在 LoggerWindow 中的 __init__ 方法中将 QTextEditLogger 实例化并将它添加为 logger 的 handler。当 LoggerWindow 被删除时, QTextEditLogger 也被删除,包括它的 QPlainTextEdit widget。

后来,当 logger 试图写入到 QTextEditLogger 时, QTextEditLogger 已经不存在了,它的 QPlainTextEdit 也被删除了,所以会发生“内部 C++ 对象已删除”的错误。

为了解决这个问题,你可以在 LoggerWindow 被删除时移除 QTextEditLogger 作为 logger 的 handler:

class LoggerWindow(QWidget):
    ...

    def closeEvent(self, event):
        logging.getLogger().removeHandler(self.logger_text_edit)
        self.deleteLater()

这样做可以确保在 QTextEditLogger 被删除之前,logger 不再尝试使用它。

另外,你也可以使用 Qt 的信号和槽机制来检测窗口何时关闭,而不是依赖 self.deleteLater() destroyed 信号:

class LoggerWindow(QWidget):
    ...

    def closeEvent(self, event):
        logging.getLogger().removeHandler(self.logger_text_edit)
        # 发出窗口关闭的信号
        self.close_signal.emit()
        event.accept()

    def __init__(self):
        ...
        # 创建 close_signal 信号
        self.close_signal = Signal()

class MainWindow(QWidget):
    ...

    def button_clicked(self):
        self.logger_window = LoggerWindow()
        self.logger_window.show()
        # 连接 close_signal 信号到槽函数
        self.logger_window.close_signal.connect(self.on_logger_window_closed)

    def on_logger_window_closed(self):
        # 在这里处理 logger 窗口关闭的逻辑
        print("Logger window closed!")

这样,当 LoggerWindow 关闭时, close_signal 信号会被发射, MainWindow 中的 on_logger_window_closed 槽函数会被调用,你可以在该函数中处理窗口关闭的逻辑。

标签:python,pyqt,pyside
From: 78830505

相关文章

  • Python中使用正则表达式
    摘要:正则表达式,又称为规则表达式,它不是某种编程语言所特有的,而是计算机科学的一个概念,通常被用来检索和替换某些规则的文本。一.正则表达式的语法①行定位符行定位符就是用来描述字符串的边界。"^"表示行的开始,"$"表示行的结束。^tm  #tmequalTomorrowMoon可以......
  • 如何在python中使用xarray打开grib2文件?
    将xarray导入为xr导入cfgrib导入生态码将pandas导入为pddata=xr.open_dataset(r"C:\Users\new\forecast_data.grib2",engine="cfgrib")这是我的代码。我只想使用xarray读取这个文件。错误是:无法识别的引擎cfgrib必须是以下之一:['netcdf4'、'scipy'、'......
  • 如何在 java 或 python 中使用 HTTP(S) 解决无法解析的主机名或无法识别的名称错误?
    我尝试以编程方式访问网站的信息,但在Java和Python上都无法解析主机名。如果我指定IP地址,则会将错误更改为TLSV1_UNRECOGNIZED_NAME。不过,这个网站无需任何额外的工作就可以通过任何浏览器解决。我在这里浏览了很多潜在的解决方案,但对于Python,它说这个问题应该在2.7......
  • Python 请求 POST 请求与 websockets 库一起使用时挂起
    我使用Python中的requests库发送POST请求,同时维护与websockets库的WebSocket连接:importasyncioimportrequestsimportwebsocketsasyncdefwebsocket_handler(uri):asyncwithwebsockets.connect(uri)aswebsocket:whileTrue:me......
  • 在Python中,list1[::] = list2的空间复杂度是多少?
    此代码首先迭代列表nums,更新整数0、1、2(也分别称为红色、白色和蓝色)的计数。nums保证只有整数0、1和/或2。找到计数后,代码使用[::],这是一种就地修改列表的技巧,以排序numsdefsortColors(self,nums:List[int])->None:re......
  • [附开题]flask框架高校资产管理系统d8y3s(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育事业的快速发展,高校资产规模日益庞大,种类繁多,管理难度显著增加。传统的资产管理方式往往依赖于手工记录和纸质档案,不仅效率低......
  • [附开题]flask框架贺州图特产管理系统uuy79(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景贺州,这座历史悠久、文化底蕴深厚的城市,以其丰富的自然资源和独特的地理位置孕育了众多令人瞩目的特产。然而,在信息化快速发展的今天,贺州特......
  • [附开题]flask框架红枫超市会员管理系统ew5iq(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着零售行业的快速发展与消费者需求的日益多样化,超市作为人们日常生活中不可或缺的一部分,其管理效率和服务质量直接影响着顾客的购物体验......
  • PYTHON专题-(4)python叫你搞对象
    什么是面向过程编程?面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。什么是面向对象编程?面向对象编程——ObjectOrientedProgramming,简......
  • 5、Qt-pyqt6常用基本控件 - 按钮控件
    Buttons--按钮类控件名说明PushButton按钮ToolButton工具按钮RadioButton单选按钮CheckBox复选框CommandLinkButton命令链接按钮DialogButtonBox对话框按钮盒......