PyQT 崩溃(底层 C/C++ 对象已被删除)“在”清空 QTreeWidget 后
我正在尝试为一个QTreeWidget构建实时搜索功能,也就是说我有一个QLineEdit,当我输入时,它会过滤QTreeWidget中显示的结果。
目前,我是通过QTreeWidget.findItems()来获取“仍然显示的项目”。
foundItems = mainForm.ui.treeShips.findItems(text,QtCore.Qt.MatchContains)
然后,我用
mainForm.ui.treeShips.clear()
来清空QTreeWidget(mainForm.ui.treeShips)。
接着,我想用
mainForm.ui.treeShips.addTopLevelItems(foundItems)
将“仍然显示的项目”添加回去,但程序却崩溃了,提示“底层的C/C++对象已被删除”。
我最初的想法是,清空treeShips时,foundItems的内容也被清空了,因为foundItems中的对象(print(foundItems))和treeShips中的对象有相同的地址,当程序想要使用这个列表时就崩溃了。
有没有人知道怎么解决这个问题,或者有没有更好的方法来实现这样的“搜索过滤”?
(希望我能正确描述我的问题 :))
谢谢,祝好!
2 个回答
每当你在一个 QTreeWidgetItem
上调用 clear
函数时,里面的项目都会被删除,所以你遇到的错误并不奇怪。你可以在下面的 QTreeWidget
实现的摘录中看到这一点:
void QTreeWidget::clear()
{
Q_D(QTreeWidget);
selectionModel()->clear();
//the treeModel here is QTreeModel, refer to snippet below
d->treeModel()->clear();
}
void QTreeModel::clear()
{
SkipSorting skipSorting(this);
for (int i = 0; i < rootItem->childCount(); ++i) {
QTreeWidgetItem *item = rootItem->children.at(i);
item->par = 0;
item->view = 0;
delete item;
}
....
}
关于你提到的搜索功能,这里有一个不错的示例,展示了如何实现搜索功能(不是实时的)。点击这里查看。虽然是C++代码,但希望你能理解。
如果你想要实现实时搜索,你需要将 QLineEdit
的 void textChanged(const QString & text)
信号连接到一个处理搜索的槽函数。
希望这能解答你的问题。
我找到了一个解决办法,灵感来自Neox的第二个想法。
我遍历树中的所有项目,把隐藏标志设置为真(setHidden(True)),然后再遍历找到的项目,把隐藏标志设置为假(我觉得这样可以,因为这两个列表的地址是一样的)。
for item in mainForm.ui.treeShips.findItems("",QtCore.Qt.MatchContains):
item.setHidden(True)
for item in foundItems:
item.setHidden(False)
不过我不知道这样做是不是有点不太干净,但确实有效 :)
希望这能帮助到其他遇到同样问题的人。