이 이미지와 같이 QTreeView에 표시되는 트리 계층 구조로 XML 데이터 집합이 포함 된 사용자 지정 QAbstractItemModel 파생 모델을 만들었습니다 :원본 모델에서 행을 삭제할 때 QSortFilterProxyModel이 충돌 함
http://imageshack.us/photo/my-images/840/xmltreeview.png
이 모델은 성공적으로 ModelTest과 몇 가지 기본적인 편집 테스트를 통과했다. 그러나 모델을 몇 가지 다른보기로 나눌 수 있도록이 모델에서 필터링을 시도 할 때 몇 가지 문제가 발생했습니다. QSortFilterProxyModel 시도하고 많이 충돌합니다. 수정 한 후에도 모델에서 행을 제거하려고 시도한 후에도 여전히 충돌합니다.
ratbr QModelIndex (0,0,0xd162000, CGHXmlModel (0xb197e68)) 0 0
RR의 QModelIndex (0,0,0xd162000, CGHXmlModel)을 (0xb197e68를 : 충돌이 발생하는 경우
콘솔 응용 프로그램은 이러한 메시지를 보여줍니다) 0 0
이것은 충돌이 일어난 호출 스택입니다 : 내가 Qt는 모델/뷰 프로그래밍에 여전히 아주 새로운 해요
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
이 오류가 정말로있다 겁에 질 렸고 날 동안 내 머리를 긁적 거렸다. 나는 내 머리를 모두 잃기 전에 여기있는 누군가가 나를 도울 수 있기를 바랍니다! 감사!
편집 : 업데이트 한 QTreeView 각 일부 소스 코드
내 테스트 프로젝트는 두 개의 대화 창문이를 포함합니다. 하나는 QAbstractItemModel 파생 클래스 멤버가 들어있는 주 창이고 다른 하나는 QSortFilterProxyModel 파생 클래스 멤버가 들어있는 자식 창입니다. 또한 자식 창에는 실제 모델에 대한 QAbstractItemModel 포인터가 있습니다.
메인 창 :
class CGHXMLModelDialog : public QDialog
{
Q_OBJECT
...
private:
Ui::CGHXMLModelDialog *ui;
CGHXmlModel* m_mainModel;
CGHXMLParameterDialog* m_ParamDialog;
...
}
자식 창
class CGHXMLParameterDialog : public QDialog
{
Q_OBJECT
...
private:
void setupProxyModel();
Ui::CGHXMLParameterDialog* ui;
QAbstractItemModel* m_coreModel;//A CGHXMLModel
CGHXMLSortFilterProxyModel* m_ParamModel;
...
}
CGHXMLModelDialog의 생성자에서 :
CGHXMLParameterDialog::CGHXMLParameterDialog(QAbstractItemModel* coreModel, QWidget *parent) :
QDialog(parent),
ui(new Ui::CGHXMLParameterDialog),
m_coreModel(coreModel)
{
ui->setupUi(this);
setupProxyModel();
}
void CGHXMLParameterDialog::setupProxyModel()
{
m_ParamModel = new CGHXMLSortFilterProxyModel(this);
m_ParamModel->setSourceModel(m_coreModel);
m_ParamModel->setFilterRegExp(QRegExp("Parameter"));
m_ParamModel->setFilterKeyColumn(0);
m_ParamModel->setDynamicSortFilter(true);
ui->CGHXMLParamView->setModel(m_ParamModel);
}
: 다음 setupProxyModel() 메서드를 호출
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);
필자는 삽입 행을 테스트하고, 행 내용을 편집하고, 열 편집을 통해 XML 특성을 삽입했습니다 (사용자 정의 열 조작; 나는 소스 모델에 대해 직접적으로 설명하지 않을 것입니다.) 그리고 Sort-Filter 모델의 존재 여부에 상관없이 작동했습니다. 이 문제는 정렬 필터 모델이 첨부되어있을 때 내 모델의 XML 요소 인 "행"을 삭제하려고 할 때 발생합니다.() 잘못 layoutChanged을 방출하는 것입니다 :
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.
업데이트 : 메인 창에서 버튼 이벤트 핸들러에 의해 불려
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;
}
가 : 여기
는 removeRows 내 코드입니다 layoutAboutToBeChanged()를 내보내지 않고?
행을 제거한 코드 부분 (관련 주변 선 포함)을 게시 할 수 있습니까? –
관련 코드를 추가했습니다. – ksming
QSortFilterProxyModel 및 QAbstractItemModel 및 문서의 구현 코드를 살펴본 후에 layoutChanged()를 내리기 전에 내 removeRows/removeColumns에서 layoutAboutToBeChanged()를 한 번만 내 보내지 않았다는 것을 알았습니다. 그것이 문제인지 궁금하다. 그러나 다시 한번, removeRows 함수에서 신호를 내보내는 예제를 본 적이 없으며 완벽하게 작동합니다. : – ksming