Xml 当通过源模型函数从源模型中删除行时,QSortFilterProxyModel崩溃
我创建了一个自定义QAbstractItemModel派生模型,该模型包含一组XML数据,这些数据以树层次结构的方式显示在QTreeView中,如下图所示: 该模型已成功通过模型测试和一些基本编辑测试。但是,我在尝试对该模型进行一些过滤时遇到了一些问题,因此我可以将该模型拆分为几个不同的视图。我试过QSortFilterProxyModel,它经常崩溃。经过一些修复后,它在尝试从模型中删除一行后仍然崩溃 控制台应用程序在崩溃发生时显示以下消息: ratbr QModelIndex(0,0,0xd162000,CGHXmlModel(0xb197e68))0 rr QModelIndex(0,0,0xd162000,CGHXmlModel(0xb197e68))0 这是崩溃发生时的调用堆栈:Xml 当通过源模型函数从源模型中删除行时,QSortFilterProxyModel崩溃,xml,qt,model,filter,treeview,Xml,Qt,Model,Filter,Treeview,我创建了一个自定义QAbstractItemModel派生模型,该模型包含一组XML数据,这些数据以树层次结构的方式显示在QTreeView中,如下图所示: 该模型已成功通过模型测试和一些基本编辑测试。但是,我在尝试对该模型进行一些过滤时遇到了一些问题,因此我可以将该模型拆分为几个不同的视图。我试过QSortFilterProxyModel,它经常崩溃。经过一些修复后,它在尝试从模型中删除一行后仍然崩溃 控制台应用程序在崩溃发生时显示以下消息: ratbr QModelIndex(0,0,0x
0 QSortFilterProxyModelPrivate::index_to_iterator qsortfilterproxymodel.cpp 193 0x0134714b
1 QSortFilterProxyModel::parent qsortfilterproxymodel.cpp 1654 0x0111a677
2 QModelIndex::parent qabstractitemmodel.h 389 0x6a2ad95e
3 QPersistentModelIndex::parent qabstractitemmodel.cpp 347 0x6a1f7320
4 QItemSelectionRange::isValid qitemselectionmodel.h 108 0x01341ea4
5 QItemSelectionModel::isSelected qitemselectionmodel.cpp 1187 0x010f0b58
6 QTreeView::drawRow qtreeview.cpp 1602 0x010db133
7 QTreeView::drawTree qtreeview.cpp 1441 0x010da4f4
8 QTreeView::paintEvent qtreeview.cpp 1274 0x010d9bed
9 QWidget::event qwidget.cpp 8333 0x00c1492d
10 QFrame::event qframe.cpp 557 0x00f8e6bc
11 QAbstractScrollArea::viewportEvent qabstractscrollarea.cpp 1043 0x0101bf0f
12 QAbstractItemView::viewportEvent qabstractitemview.cpp 1619 0x010a5785
13 QTreeView::viewportEvent qtreeview.cpp 1256 0x010d9aa3
14 QAbstractScrollAreaPrivate::viewportEvent qabstractscrollarea_p.h 100 0x01276a13
15 QAbstractScrollAreaFilter::eventFilter qabstractscrollarea_p.h 116 0x0127506c
16 QCoreApplicationPrivate::sendThroughObjectEventFilters qcoreapplication.cpp 847 0x6a1ffc73
17 QApplicationPrivate::notify_helper qapplication.cpp 4392 0x00bc96e5
18 QApplication::notify qapplication.cpp 4361 0x00bc9586
19 QCoreApplication::notifyInternal qcoreapplication.cpp 732 0x6a1ff9dc
20 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 218 0x0123d53e
我对Qt模型/视图编程还是相当陌生的,这个错误真的让人望而生畏,让我好几天都摸不着头脑。我希望这里的人能在我掉光头发之前帮我一把!谢谢
编辑:更新以包含一些源代码
我的测试项目有两个对话框窗口,每个窗口有一个QTreeView。一个是包含QAbstractItemModel派生类成员的主窗口,另一个是包含QSortFilterProxyModel派生类成员的子窗口。子窗口还有一个指向实际模型的QAbstractItemModel指针
主窗口:
class CGHXMLModelDialog : public QDialog
{
Q_OBJECT
...
private:
Ui::CGHXMLModelDialog *ui;
CGHXmlModel* m_mainModel;
CGHXMLParameterDialog* m_ParamDialog;
...
}
void CGHXMLModelDialog::on_deleteRowButton_clicked()
{
QModelIndex currIndex = ui->CGHXMLTreeView->selectionModel()->currentIndex();
if(!m_mainModel->removeRow(currIndex.row(), currIndex.parent()))
{
qDebug() << "Fail to remove row from Model.";
return;
}
}
//Program crashes after this function returns.
子窗口:
class CGHXMLParameterDialog : public QDialog
{
Q_OBJECT
...
private:
void setupProxyModel();
Ui::CGHXMLParameterDialog* ui;
QAbstractItemModel* m_coreModel;//A CGHXMLModel
CGHXMLSortFilterProxyModel* m_ParamModel;
...
}
在CGHXMLModelDialog构造函数中:
m_mainModel = new CGHXmlModel(theDomDocument, this);
ui->CGHXMLTreeView->setModel(m_mainModel);
//Create sub-dialog window containing proxy filter model
m_ParamDialog = new CGHXMLParameterDialog(m_mainModel, this);
然后调用setupProxyModel()方法:
我已经在源模型上直接测试了插入行、编辑行内容、通过列编辑(自定义列操作;我将不详细说明)插入XML属性等,并且它在有或没有排序过滤器模型的情况下都可以工作。当我试图删除一个“行”时会出现问题,该行是我的模型的一个XML元素,但它附带了一个排序过滤器模型
以下是我的代码:
bool CGHXmlModel::removeRows(int rowposition, int rows, const QModelIndex &parent)
{
CGHXMLTreeItem *parentItem = getItem(parent);
bool success = false;
beginRemoveRows(parent, rowposition, rowposition + rows - 1);
success = parentItem->removeChildren(rowposition, rows);
endRemoveRows();
if(success)//Works!
{
emit layoutChanged();
}
return success;
}
由主窗口中的按钮事件处理程序调用:
class CGHXMLModelDialog : public QDialog
{
Q_OBJECT
...
private:
Ui::CGHXMLModelDialog *ui;
CGHXmlModel* m_mainModel;
CGHXMLParameterDialog* m_ParamDialog;
...
}
void CGHXMLModelDialog::on_deleteRowButton_clicked()
{
QModelIndex currIndex = ui->CGHXMLTreeView->selectionModel()->currentIndex();
if(!m_mainModel->removeRow(currIndex.row(), currIndex.parent()))
{
qDebug() << "Fail to remove row from Model.";
return;
}
}
//Program crashes after this function returns.
void CGHXMLModelDialog::on_deleteRowButton_clicked()
{
QModelIndex currendex=ui->CGHXMLTreeView->selectionModel()->currendex();
如果(!m_mainModel->removeRow(currIndex.row(),currIndex.parent()))
{
qDebug()您知道QAbstractItemModel和QSortFilterProxyModel中的索引不能混合吗
如果您的filterProxy模型中有QModelIndex,则需要使用QAbstractProxyModel::mapToSource()将其从项模型转换为QModelIndex。我通过注释行“emit layoutChanged()”解决了此问题对于我的insertRows,removeRows方法。最初代码没有这一行,但QTreeView的更新问题迫使我将其包括在内,而没有包括“emit LayoutBoutotochanged()”。由于某种原因,更新问题似乎消失了
无论如何,感谢那些试图帮助我的人。在不久的将来,我肯定会需要更多的帮助。你能发布代码的一部分(以及相关的周边行)吗删除行的位置?我已经添加了相关代码。在查看QSortFilterProxyModel和QAbstractItemModel的实现代码以及文档后,我才意识到在发出layoutChanged()之前,我没有在我的RemoveOWS/removeColumns中发出LayoutAboutBeChanged().我想知道这是否是问题所在?但是,再一次,我从未见过任何一个示例在其RemoveOWS功能中发出任何一种信号,并且仍能正常工作:(我知道它们不能混合,但在我的测试项目中,我使用包含源模型的QTreeView的选择模型直接编辑、添加和删除行。QSortFilterProxyModel子类的QTreeView位于另一个窗口上,仅用于查看目的(现在是这样)。在任何情况下,我都会记下您在后期编码阶段的提示。您是否在插入代码周围调用了begin/endInsertRows()?LayoutAboutChanged应该是LayoutAboutBeChanged