使用pytest-qt测试PyQt5组件时报wrapped C/C++ object已删除错误如何解决?
问题诱因
核心原因是对象生命周期提前结束:你创建LogTableView时传入的父部件QtWidgets.QSplitter()是临时对象,没有被Python代码的变量引用,创建完成后立刻就被Python垃圾回收机制销毁。而Qt的父子对象体系中,父对象被销毁时会自动销毁所有子对象,所以你创建的LogTableView对应的C底层对象也跟着被一并删除。后续调用resizeEvent方法时,Python层面的实例还存在,但绑定的C对象已经被释放,就触发了该RuntimeError。
你之前尝试修改super调用的写法没有效果,因为问题本质和父类调用逻辑完全无关。
解决方案
两种可行方案任选即可:
- 方案1:单独持有父部件对象,避免被提前回收
def test_resize_event_should_result_in_resize_rows(request, qtbot): t_logger.info(f'\n>>>>>>> test name: {request.node.originalname}') # 单独定义变量持有splitter,避免被GC回收 splitter = QtWidgets.QSplitter() table_view = logger_table.LogTableView(splitter) table_view.resizeEvent(QtGui.QResizeEvent(QtCore.QSize(10, 10), QtCore.QSize(20, 20)))
- 方案2:使用qtbot托管部件生命周期(pytest-qt最佳实践)
不需要手动管理parent,qtbot会自动维护部件生命周期直到测试结束:
def test_resize_event_should_result_in_resize_rows(request, qtbot): t_logger.info(f'\n>>>>>>> test name: {request.node.originalname}') table_view = logger_table.LogTableView() # 注册部件到qtbot qtbot.addWidget(table_view) table_view.resizeEvent(QtGui.QResizeEvent(QtCore.QSize(10, 10), QtCore.QSize(20, 20)))
如果需要更贴合实际运行场景测试resize逻辑,也可以直接调用table_view.resize(10,10)触发重绘,不需要手动构造QResizeEvent调用resizeEvent。
内容的提问来源于stack exchange,提问作者mike rodent
相关产品推荐
相关产品推荐

