2011-08-31 4 views
3

이 이미지와 같이 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()를 내보내지 않고?

+0

행을 제거한 코드 부분 (관련 주변 선 포함)을 게시 할 수 있습니까? –

+0

관련 코드를 추가했습니다. – ksming

+0

QSortFilterProxyModel 및 QAbstractItemModel 및 문서의 구현 코드를 살펴본 후에 layoutChanged()를 내리기 전에 내 removeRows/removeColumns에서 layoutAboutToBeChanged()를 한 번만 내 보내지 않았다는 것을 알았습니다. 그것이 문제인지 궁금하다. 그러나 다시 한번, removeRows 함수에서 신호를 내보내는 예제를 본 적이 없으며 완벽하게 작동합니다. : – ksming

답변

1

내 insertRows, removeRows 메소드에 대해 "emit layoutChanged()"행을 주석 처리하여이 문제를 해결했습니다. 원래 코드에는이 줄이 없었지만 QTreeView의 업데이트 문제로 인해 "layoutAboutToChanged()"를 포함하지 않고 포함시켜야했습니다. 어떤 이유로 업데이트 문제가 사라진 것 같습니다.

어쨌든 도움을 주신 분들께 감사드립니다. 나는 가까운 시일 내에 더 많은 것을 분명히 필요로 할 것입니다.

+0

삽입 코드 주위에 begin/endInsertRows()를 호출 했습니까? – mlvljr

+0

layoutAboutToChanged는 layoutAboutToBeChanged로되어 있습니다. –

1

QAbstractItemModel 및 QSortFilterProxyModel의 인덱스를 혼합 할 수 없다는 것을 알고 있습니까?

filterProxy 모델의 QModelIndex가있는 경우 QAbstractProxyModel :: mapToSource()를 사용하여 항목 모델에서 QModelIndex로 변환해야합니다.

+0

나는 혼합 할 수 없다는 것을 알고 있지만 테스트 프로젝트에서는 소스 모델을 직접 포함하는 선택 모델을 사용하여 행을 편집, 추가, 삭제했다 .QSortFilterProxyModel 서브 클래스의 QTreeView는 다른 창에있다. (현재는 그럴 것입니다.) 어쨌든 코딩의 후반 단계에 대한 팁을 확실히 메모 할 것입니다. – ksming

관련 문제