2017-12-21 17 views
0

뷰가 QTreeView 기반 클래스이고 모델이 QAbstractItemModel 기반 클래스 인 Qt 기반 트리 뷰를 구현하고 있습니다. 나무는 수백만 개의 노드를 가지고 있다고 가정합니다. 필터링 된 노드를 트리보기에 그냥 숨기는 필터링 메커니즘을 구현하고 있습니다. (나는 QSortFilterProxyModel을 사용하고 싶지 않다.)QAbstractItemModel 파생 모델에서 숨길 행에 플래그를 지정하는 방법

모델의 내부 데이터 구조는 다소 비슷하다.

class MyTreeItem 
{ 
... 
private: 
     QList<MyTreeItem *> _children; 
     bool    _isHidden; 
}; 

class MyTreeModel : public QAbstractItemModel 
{ 
    ... 
    private: 
     MyTreeItem * _rootNode; 
    }; 

I 모델 데이터 구조가 채워되는 동안 특정 노드 (MyTreeItem *)가 필터링되어야 하는지를 결정할 수있다. 따라서 QTreeView가 전체 트리를 다시 가로 지르고 데이터를 채운 후 행을 숨기지 않고 데이터 구조를 채우는 동안이 항목을 숨겨야한다는 사실을 알리고 자합니다.

솔직히 나는 디자인 단계에 있으므로 실제 코드가 없습니다. 내 요구 사항은 데이터 구조를 채우는 동안 현재 노드를 필터링해야하는지 여부를 결정하고, 그렇다면 플래그 _isHidden을 설정합니다. 그러나 나는보기를 QTreeView::setRowHidden() 또는 기타 다른 방법으로 호출하여 행을 숨길 때를 알 수있는 방법을 모르겠습니다.

최선의 방법에 대한 의견을 공유해주세요. 감사합니다. .

+0

왜 ['QSortFilterProxyModel'] (http://doc.qt.io/qt-5/qsortfilterproxymodel.html)을 사용하지 않으시겠습니까? 당신이 제공 한 설명에서 그것은 작업을위한 올바른 도구 일 것입니다. –

+0

@ G.M. 프로젝트 팀은'QSortFilterProxyModel '을 사용하는 것이 성능에 부담이된다고 결정했습니다. 그래서 그것은 방정식에서 벗어나야합니다. – susiriss

+0

모델에 항목을 표시하지 않으려면 왜 그 항목을 포함시켜야합니까? 그냥 추가하지 마십시오. –

답변

0

표준 Qt 모델 항목보기에서 셀 (또는 행)을 숨기려면 built-in data flags이 없습니다. 항목을 비활성화하거나 선택할 수 없도록 설정할 수는 있지만 완전히 숨길 수는 없습니다.

물론 모델을 반복하여 QTreeView::setRowHidden()을 수동으로 호출 할 수도 있지만 그렇게하고 싶지는 않다는 것을 나타내므로 동의하는 경향이 있습니다 (프록시 모델을 사용하는 것이 훨씬 효율적이고 실용적입니다).

따라서 항목보기 중 하나를 하위 클래스로 지정하여 원하는 효과를 얻고 사용자 지정 플래그를 기반으로 항목을 필터링해야 할 가능성이 큽니다. item delegate 경로가 있습니다 (모델이 아닌보기 수준에서도 설정 됨). 그래서 그림을 그려 보지 않고 필드를 필터링 할 수 있습니다 (그러나 결코 시도하지 않았습니다).

또는 의견에서 제안한대로 QSortFilterProxyModel을 사용하십시오. 이는 사용자가 요구하는대로 정확하게 설계되었으며 (실제로 현대 하드웨어의 일반적인 GUI 응용 프로그램에 눈에 띄는 오버 헤드를 추가하지는 않을 것입니다). 자신 만의 프록시 모델을 작성할 수도 있습니다. 예를 들어, QSortFilterProxyModel code의 부품 만 사용할 수 있습니다.

또는 이미 제안했듯이 모델을 만들 때 원하지 않는 행을 포함시키지 마십시오.

+0

모델을 빌드 할 때 필터가 변경 될 때마다 모델의 데이터 소스가 순차적 소스이므로 전체 모델을 다시 빌드해야한다는 점에서 숨겨진 행을 포함하지 않으려 고합니다. 그건 나에게 잔인한 것처럼 보입니다. 귀하의 제안에서 내보기 QTreeView보기를 서브 클래 싱하는 것이 나에게 더 나은 옵션을 보인다. 'QAbstractItemView :: isIndexHidden()'은이 경우 무시할 메소드와 비슷합니다. 이 방법을 사용하는 것에 대한 아이디어가 있습니까? 도움이되는 답변을 위해 시간을내어 주셔서 감사합니다. – susiriss

+0

'isIndexHidden()'은 상태를 쿼리하는 방법 일뿐입니다.나는 당신이하고있는 것을 한 번도 해보지 않아서 어떤 것이 가장 잘 작동 할 지 모르겠습니다. ''QTableView' (https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qtableview.h.html)에 대한 코드를 보면,'setRowHidden()'은 단지'setSectionHidden() '라고 표시합니다. 그런 다음 [QTableView :: paintEvent()] (https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qtableview.cpp.html#1343)에서 세로줄을 확인하여 행이 건너 뛴다. 그래서 대신'QHeaderView'를 다시 구현하는 것이 더 나을지 궁금합니다. –