Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 当通过源模型函数从源模型中删除行时,QSortFilterProxyModel崩溃_Xml_Qt_Model_Filter_Treeview - Fatal编程技术网

Xml 当通过源模型函数从源模型中删除行时,QSortFilterProxyModel崩溃

Xml 当通过源模型函数从源模型中删除行时,QSortFilterProxyModel崩溃,xml,qt,model,filter,treeview,Xml,Qt,Model,Filter,Treeview,我创建了一个自定义QAbstractItemModel派生模型,该模型包含一组XML数据,这些数据以树层次结构的方式显示在QTreeView中,如下图所示: 该模型已成功通过模型测试和一些基本编辑测试。但是,我在尝试对该模型进行一些过滤时遇到了一些问题,因此我可以将该模型拆分为几个不同的视图。我试过QSortFilterProxyModel,它经常崩溃。经过一些修复后,它在尝试从模型中删除一行后仍然崩溃 控制台应用程序在崩溃发生时显示以下消息: ratbr QModelIndex(0,0,0x

我创建了一个自定义QAbstractItemModel派生模型,该模型包含一组XML数据,这些数据以树层次结构的方式显示在QTreeView中,如下图所示:

该模型已成功通过模型测试和一些基本编辑测试。但是,我在尝试对该模型进行一些过滤时遇到了一些问题,因此我可以将该模型拆分为几个不同的视图。我试过QSortFilterProxyModel,它经常崩溃。经过一些修复后,它在尝试从模型中删除一行后仍然崩溃

控制台应用程序在崩溃发生时显示以下消息:

ratbr QModelIndex(0,0,0xd162000,CGHXmlModel(0xb197e68))0

rr QModelIndex(0,0,0xd162000,CGHXmlModel(0xb197e68))0

这是崩溃发生时的调用堆栈:

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