2017-12-21 51 views
0

QTベースのツリービューを実装しています。このビューは、QTreeViewベースのクラスで、モデルはQAbstractItemModelベースのクラスです。ツリーには数百万のノードがあるはずです。フィルタリングされたノードがツリービューに隠れているフィルタリングメカニズムを実装しています。 (私はQSortFilterProxyModelを使用したくない)QAbstractItemModelの派生モデルで非表示にする行をフラグする方法

モデルの内部データ構造は、このように見えます。

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

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

モデルデータ構造が入力されている間に特定のノード(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()を手動で呼び出すこともできますが、そうしたくない場合は、私は同意する傾向があります(プロキシモデルを使用する方が効率的かつ実用的でしょう)。

したがって、アイテムビューの1つをサブクラス化して目的の効果を得、カスタムフラグに基づいてフィルタリングすることが最も一般的です。 item delegateルートもあります(モデルではなく、ビューレベルでも設定されています)。そのため、フィールドを単にペイントしないでフィルタリングすることができます。

コメントの中に示唆されているように、あなたが聞いている通りに設計されています(現代のハードウェアの典型的なGUIアプリケーションには目立ったオーバーヘッドを追加するつもりはありません)。QSortFilterProxyModelを使用してください。独自のプロキシモデルを作成することもできます。たとえば、必要なのは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'を再実装する方が良いかもしれないのだろうかと思います。 –

関連する問題