データ駆動型アプリケーションの多くにおいて、ソートやフィルタリングは非常に一般的であり、しばしば必要不可欠です。Qtは、元のデータを変更することなくソートやフィルタリングを処理できる組み込みのプロキシモデルを提供することで、これを容易にします。このモデルはビューにアタッチでき、MVCフレームワーク内でデータ表示に使用できます。開発者はQSortFilterProxyModelを継承し、そのフィルタリングおよびソートAPIをオーバーライドすることで機能を拡張でき、完全にカスタマイズされた動作を実現できます。これにより、開発者はこれらの機能をゼロから構築する必要がなくなり、大幅な時間短縮が図れます。同時に、必要に応じて柔軟にカスタマイズする余地も残されています。
Qt Quickに関しては、現代的なUI開発パラダイムが宣言的な手法を提供し、開発者が動的でアニメーション化された高性能なユーザーインターフェースを迅速に構築することを可能にします。QMLプロパティとJavaScript式を用いた簡潔なコードは、可読性と理解しやすさも向上させます。なお、6.10以前のバージョンでは、ネイティブのQMLプロキシモデルが存在しなかったため、開発者はC++で手動でソートやフィルタリングのロジックを記述する必要がありました。これにより、異なるソーターやフィルタモデルを使用する場合、冗長なコードが生じる可能性がありました。宣言的なモデル手法により、開発者はソースデータの操作部分をUIに近接させつつ、ソースモデルに対するデータの実際のビジネスロジック処理をC++で管理することが可能となります。
Qt 6.10 では、QML の SortFilterProxyModel が提供され、宣言的な方法でモデルデータのソートとフィルタリングが可能となりました。SortFilterProxyModel は内部で QAbstractProxyModel を継承しており、QSortFilterProxyModel と同様に、ソースモデル内のデータの実際のインデックスは変更されません。ソースモデルはSortFilterProxyModelのmodel属性で設定でき、プロキシモデルはビューのmodel属性で設定できます。以下の例では、SortFilterProxyModelを使用して、ユーザーが指定した割合以上CPUを使用しているプロセスをprocessModelからフィルタリングし、それらをユーザーIDでソートする方法を説明します。
【注】 本稿の考え方や内容は、既存プロジェクトhttps://github.com/oKcerG/SortFilterProxyModelに触発され、それを基に作成されたものです。
デフォルトで提供されている特定の Filter および Sorter が用意されており、これらを適切に設定することで、ご希望の結果を得ることが可能です。リスト内で設定された個々のフィルターとソーターには優先順位を付けることもでき、これによりデータに適用される操作の順序が決まります。例えば、まずCPU使用率に基づいてデータをフィルタリングし、その後プロセスIDでさらにソートするように設定することが可能です。
モデル内のデータは、指定された列に基づいてフィルタリングすることが可能です。これにより、すべての列に対してではなく、選択的にフィルタを適用することが可能となります。この動作はfilterKeyColumnプロパティと同様であり、個々のフィルタごとに設定可能となるよう設計されています。なお、ここで参照される列インデックスは、視覚的なインデックスではなく論理的なインデックスに対応している点にご留意ください。
正規表現を用いたデータフィルタリング(setFilterRegularExpressionと同様の機能)は、FunctionFilter(および同様のQMLコンストラクトであるFunctionSorterによるソート)を通じて実現できます。この際、対象となるコンポーネント内で指定された対応するrole名を使用します。
SortFilterProxyModel のドキュメントには、対応するフィルターおよびソーターのプロパティに関する詳細な説明と、それに関連する情報が記載されております。SortFilterProxyModel は、データ操作においてQSortFilterProxyModel とほぼ同様のアルゴリズムを内部的に使用し、採用しております。この機能はバージョン 6.10 時点では技術プレビュー段階となりますため、フィードバックに基づき API の変更が生じる可能性がございます。あらかじめご了承ください。
今後のバージョンでは、ネストされたフィルターとソーターのサポートを検討しております。
現在のmodel属性はQAbstractItemModelのみをサポートしております。しかしながら、SortFilterProxyModel内のモデルの実際の型はQVariantとして選択されており、将来的にはJavaScript配列のサポートも拡張可能となります。
また、カスタムフィルターやソーターの定義は、現時点ではベースが内部仕様であるため不可能です。この要件に対応するため、将来的には公開される可能性があります。
本ブログをお読みいただきありがとうございます。本機能の改善に向けたご意見・ご感想をいただければ、大変参考になります。