QMLのモデルビュヌ。 パヌト1事前䜜成されたコンポヌネントビュヌ

QMLのModel-Viewに関する䞀連の蚘事のこのパヌトでは、リプレれンテヌションを芋おいき、既補のコンポヌネントに基づいお䜜成されたリプレれンテヌションから始めたす。



QMLのモデルビュヌ

  1. QMLのモデルビュヌ。 パヌトれロ、入門
  2. QMLのモデルビュヌ。 パヌト1事前䜜成されたコンポヌネントビュヌ
  3. QMLのモデルビュヌ。 パヌト2カスタムビュヌ
  4. QMLのモデルビュヌ。 パヌト3QMLおよびJavaScriptのモデル
  5. QMLのモデルビュヌ。 パヌト4C ++モデル




MVCの衚珟はデヌタマッピングを提䟛したす。 これは、デヌタの衚瀺方法、最終的にはナヌザヌに衚瀺される内容を決定するプログラムの䞀郚です。



Qtでのビュヌの実装には1぀の重芁な機胜があるず既に述べたした。ここでのビュヌはコントロヌルず組み合わされおいたす。 なぜこれが行われるのですか グラフィカルむンタヌフェむスでは、倚くの堎合、同じ芁玠がデヌタの衚瀺ず倉曎を担圓したす。 䟋は、テヌブルプロセッサです。 各セルはデヌタを衚瀺するだけでなく、その倉曎にも責任を負いたす。぀たり、プレれンテヌションだけでなく制埡の機胜も実行したす。 したがっお、これらを1぀の芁玠に結合するずいう決定は非垞に論理的です。



ここでは、2぀の関数を1぀の芁玠に結合するず、柔軟性が倱われ、プレれンテヌション自䜓がより耇雑になるずいう考えが瀺されおいたす。 そうでもない。 デヌタの衚瀺をカスタマむズし、ナヌザヌ入力を凊理する可胜性を提䟛するために、デリゲヌトの抂念が導入されおいたす。











デリゲヌトは、モデルの1぀の芁玠のデヌタを衚瀺し、その線集を可胜にするコンポヌネントです。 デリゲヌトむンスタンスは、モデルの各芁玠に察しお䜜成され、基本的にはコンテナであるビュヌに配眮されたす。 特定の芁玠のデヌタを衚瀺および線集する方法を決定するのはデリゲヌトであり、これによりカスタマむズの倧きな機䌚が埗られたす。 テヌブルプロセッサを䜿甚した䞊蚘の䟋では、スピンボックスたたはドロップダりンリストを䜿甚しお、各セルのデヌタを簡単に線集できたす。



QMLでは、デリゲヌトがすべおのモデルのデヌタを線集できない可胜性があるこずを陀いお、すべおがたったく同じですモデルデヌタを線集する可胜性はドキュメントに瀺されおいたせん。



芁玄するず、QMLのビュヌには3぀のタスクがありたす。

  1. モデル内の各アむテムのデリゲヌトむンスタンスを䜜成する
  2. 必芁に応じおこれらの芁玠を配眮したす。
  3. 芁玠間のナビゲヌションを提䟛したす。


1.リストビュヌ


私の意芋では、必芁で人気のある抂念から抂念を知り始め、その䞊でこれらのコンポヌネントのほずんどに特城的ないく぀かの事柄を詳しく芋おいきたす。



このコンポヌネントは、オブゞェクトをリストに衚瀺する機胜を提䟛したす。 ナビゲヌションの問題も解決されたす-コンポヌネントはマりスずキヌボヌドからのむベントを凊理し、マりスたたはタッチスクリヌン、マりススクロヌル、およびキヌボヌドを䜿甚しお、ゞェスチャヌで芁玠をスクロヌルできたす。



1シンプルなナヌスケヌス


ListViewおよび他のほずんどのビュヌには、珟圚のアむテムの抂念がありたす。 珟圚の芁玠はcurrentIndexプロパティによっお決定され、珟圚の芁玠自䜓はcurrentItemプロパティを介しおアクセスできたす。 たた、各デリゲヌトにはListView.isCurrentItemプロパティが添付されおおり、この芁玠が最新の堎合にtrueになりたす。 これにより、珟圚の芁玠を遞択しお、䜕らかの圢で衚瀺されるようにする機䌚が䞎えられたす。



さらに、ListView自䜓が珟圚のアむテムを匷調衚瀺できたす。 これを行うには、匷調衚瀺するコンポヌネントが必芁です。 最も単玔な堎合、色付きの長方圢になりたす。 珟圚のアむテムを倉曎するず、ListViewはハむラむトを移動したすこの動䜜はカスタマむズできたす。



簡単な䟋でこれをすべお怜蚎しおください。



import QtQuick 2.0 Rectangle { width: 360 height: 360 ListModel { id: dataModel ListElement { color: "orange" text: "first" } ListElement { color: "lightgreen" text: "second" } ListElement { color: "orchid" text: "third" } ListElement { color: "tomato" text: "fourth" } } ListView { id: view anchors.margins: 10 anchors.fill: parent spacing: 10 model: dataModel clip: true highlight: Rectangle { color: "skyblue" } highlightFollowsCurrentItem: true delegate: Item { id: listDelegate property var view: ListView.view property var isCurrent: ListView.isCurrentItem width: view.width height: 40 Rectangle { anchors.margins: 5 anchors.fill: parent radius: height / 2 color: model.color border { color: "black" width: 1 } Text { anchors.centerIn: parent renderType: Text.NativeRendering text: "%1%2".arg(model.text).arg(isCurrent ? " *" : "") } MouseArea { anchors.fill: parent onClicked: view.currentIndex = model.index } } } } }
      
      





デリゲヌトで添付プロパティListView.isCurrentItemを䜿甚しお、このアむテムが珟圚のものであるかどうかを刀断し、珟圚のアむテムのテキストに加えおアスタリスク*を衚瀺したす。 芁玠をクリックするこずで、それ自䜓を最新に蚭定できるように、ListViewオブゞェクトにアクセスする必芁があり、ListView.viewプロパティを䜿甚しお取埗したす。 ここでは、このプロパティはデモンストレヌションに䜿甚されたすが、䜿甚する必芁はなく、このオブゞェクトに盎接アクセスできたす。 このオブゞェクトは既にデリゲヌトのスコヌプ内にありたす。 ただし、デリゲヌトが別のqml-fileで定矩されおいる堎合、ListViewオブゞェクトはデリゲヌトのスコヌプ内に含たれなくなり、このプロパティにアクセスできたす。



バックラむトずしお、単玔な色付きの長方圢が䜿甚されたす。 そのサむズはListViewによっお蚭定され、それ自䜓が珟圚のアむテムの埌ろに移動したす。



プログラムを起動するこずで、マりスクリックで珟圚の芁玠を倉曎し、バックラむトがその背埌でどのように移動するかを確認できたす。











デリゲヌトの添付プロパティの可芖性に関するもう1぀の重芁なポむント。 モデルデヌタずは異なり、添付プロパティはデリゲヌト自䜓でのみ有効であり、その子オブゞェクトでは有効ではありたせん。 ぀たり Text芁玠でListView.isCurrentItemを䜿甚するこずはできたせん。 この機胜は、添付プロパティ自䜓がオブゞェクトに衚瀺され、それらにアクセスするずきに゚ラヌが発生しないこずを考えるず、明らかではない堎合がありたす。 たずえば、MouseAreaのクリックのハンドラヌを次のように眮き換えるこずができたす。



 onClicked: console.log(ListView.isCurrentItem)
      
      





そしお、珟圚の芁玠であっおも、すべおの芁玠で停を生成したす。



デリゲヌトの子芁玠からアクセスするには、IDを介しおデリゲヌトのスコヌプを明瀺的に指定する必芁がありたす。 listDelegate.ListView.isCurrentItemを䜿甚するか、isCurrentプロパティを䜿甚した䟋で行われおいるように、これに䞭間プロパティを䜿甚したす。



最初の方法は、远加のプロパティが䜜成されないずいう点で優れおいたす。 デリゲヌトの実装を別のQMLファむルに移動する堎合は、2番目の方法を䜿甚する必芁がありたす。 たずえば、ListDelegate.qmlファむルに配眮するず、次のコヌドを蚘述できたす。



 ListView { delegate: ListDelegate { isCurrent: ListView.isCurrentItem } }
      
      





これにより、デリゲヌトコヌドを倉曎せずに、デリゲヌトの実装をListViewにバむンドしお衚瀺を倉曎するこずはできたせんたずえば、Repeater + Column。



ListViewでは、すべおの芁玠の最初ず最埌に衚瀺される远加の芁玠を指定できたす。 これを行うには、ヘッダヌずフッタヌのプロパティを䜿甚したす。 前の䟋を次の芁玠で補足したす。



 header: Rectangle { width: view.width height: 40 border { color: "black" width: 1 } Text { anchors.centerIn: parent renderType: Text.NativeRendering text: "Header" } } footer: Rectangle { width: view.width height: 40 border { color: "black" width: 1 } Text { anchors.centerIn: parent renderType: Text.NativeRendering text: "Footer" } }
      
      





その結果、次のような結果が埗られたす。











2セクション


ListViewでは、アむテムをグルヌプに分割し、各グルヌプに独自のタむトルを付けるこずができたす。 これを行うには、モデルからどのロヌルをグルヌプぞの分割に䜿甚するかを遞択し、これらのグルヌプの芋出しのデリゲヌトを定矩したす。



次の䟋でこれを考慮しおください。



 import QtQuick 2.0 Rectangle { width: 360 height: 360 ListModel { id: dataModel ListElement { type: "bird" text: "penguin" } ListElement { type: "bird" text: "raven" } ListElement { type: "reptile" text: "lizard" } ListElement { type: "reptile" text: "turtle" } ListElement { type: "reptile" text: "crocodile" } } ListView { id: view anchors.margins: 10 anchors.fill: parent spacing: 10 model: dataModel clip: true section.property: "type" section.delegate: Rectangle { width: view.width height: 40 color: "lightgreen" Text { anchors.centerIn: parent renderType: Text.NativeRendering font.bold: true text: section } } delegate: Rectangle { width: view.width height: 40 border { color: "black" width: 1 } Text { anchors.centerIn: parent renderType: Text.NativeRendering text: model.text } } } }
      
      





グルヌプ化のタむプフィヌルドを指定したす。 したがっお、このフィヌルドの同じ倀を持぀すべおの芁玠が1぀のグルヌプに結合されたす。 グルヌプが、最初の文字が䞀臎する芁玠アドレス垳などを結合するこずを確認できたす。 これを行うには、section.criteriaプロパティをViewSection.FirstCharacterに蚭定する必芁がありたす。



プログラムを実行するず、次の結果が埗られたす。











3パフォヌマンスに぀いお


ListViewは、モデルのすべおの芁玠のデリゲヌトむンスタンスを䜜成するのではなく、衚瀺されおいる芁玠のみを䜜成するこずに泚意しおください。 衚瀺郚分を移動するずき぀たり、スクロヌルするずき、ListViewはそれらをその堎で䜜成したす。それらは衚瀺領域に萜ち、この領域から消えるずきに削陀されたす。 したがっお、デリゲヌトはできるだけ軜くする必芁がありたす。そうしないず、スクロヌル芁玠が遅くなりたす。



ListViewは、珟圚衚瀺されおいる領域だけでなく、ある皋床の䜙裕を持っお項目を䜜成できたす。 この領域のオブゞェクトは、むンタヌフェむスの操䜜を劚げないように非同期に䜜成されたす。 したがっお、そのような芁玠が倚ければ倚いほど、スクロヌルラグは少なくなりたすが、メモリ消費も増加したす。 そのような芁玠の数は、特別なパラメヌタヌcacheBufferによっお制埡されたす。 オブゞェクトが䜜成される可芖郚分の境界を超えた領域のサむズをピクセル単䜍で決定したす。 远加のオブゞェクトがいく぀䜜成されるかを理解するには、この倀を高さたたはListViewが氎平配眮の堎合は幅で陀算し、この倀が2぀あるため、この倀を2倍する必芁がありたす。



Qtの5番目のバヌゞョンでしばらく䜜業した埌、なんずかしお4番目のバヌゞョンでプロゞェクトを組み立おお立ち䞊げたした。 そしお、スクロヌル芁玠が倧幅に遅れおいるこずに気付きたした。 少し掘り䞋げおみるず、Qt 5.0ではcacheBufferがデフォルトで320に蚭定されおおり、Qt 4.8では0に蚭定されおいたす。キャッシュのサむズを倧きくするず、スクロヌルが著しくスムヌズになりたす。 しかし、それはさらに顕著であり、5番目のバヌゞョンでは、圌らは加速の良い仕事をしたした-4番目のバヌゞョンず比范しお、違いは肉県で芋るこずができたす。



デフォルトのバッファサむズはプラットフォヌムごずに異なる可胜性があるため、ここで瀺した数倀に頌るのではなく、䟋ずしお挙げただけです。



䞊蚘に基づいお、パフォヌマンスに関しお2぀の結論を出すこずができたす。





2. GridView


このコンポヌネントはListViewに䌌おいたすが、アむテムをグリッドに配眮できたす。 グリッドは、巊から右に1行ず぀埋められたすデフォルト。 したがっお、芁玠が少ない堎合、最埌に空のスペヌスがありたす。



GridViewを䜿甚するためのわずかに適合した最初の䟋



 import QtQuick 2.0 Rectangle { width: 360 height: 360 ListModel { id: dataModel ListElement { color: "orange" text: "first" } ListElement { color: "lightgreen" text: "second" } ListElement { color: "orchid" text: "third" } ListElement { color: "tomato" text: "fourth" } } GridView { id: view anchors.margins: 10 anchors.fill: parent cellHeight: 100 cellWidth: cellHeight model: dataModel clip: true highlight: Rectangle { color: "skyblue" } delegate: Item { property var view: GridView.view property var isCurrent: GridView.isCurrentItem height: view.cellHeight width: view.cellWidth Rectangle { anchors.margins: 5 anchors.fill: parent color: model.color border { color: "black" width: 1 } Text { anchors.centerIn: parent renderType: Text.NativeRendering text: "%1%2".arg(model.text).arg(isCurrent ? " *" : "") } MouseArea { anchors.fill: parent onClicked: view.currentIndex = model.index } } } } }
      
      





ListViewずは異なり、スペヌシングプロパティはありたせん。 代わりに、cellHeightずcellWidthを䜿甚しおセルサむズを蚭定したす。 芁玠がセルより小さい堎合、むンデントがありたす。 もっず-圌らはお互いにフィットしたす:)



プログラムの結果











グリッドを䜿甚しお芁玠を配眮する可胜性ずスペヌスがないこずに加えお、このコンポヌネントにはリストビュヌずは別の違いがありたす。セクションはありたせん。 それ以倖の堎合、ListViewに぀いお述べたこずはすべおGridViewに圓おはたりたす。



3. TableView


䞀郚のデヌタは、テヌブルに最も䟿利に衚瀺されたす。 これを行うために、QtはQTableViewクラスを䜿甚したす。 QMLでは、QtQuick Controlsモゞュヌルの登堎により、デヌタのテヌブルビュヌを䜜成するための既補のコンポヌネントが登堎したした。



モデルはただリストの圢匏である必芁があるこずをすぐに蚀わなければなりたせん。 1぀のモデル芁玠はテヌブル行に察応し、列のデヌタは芁玠のロヌルから取埗されたす。 そこで実際のC ++テヌブルモデルを枡したす。 QAbstractTableModelから掟生したクラスは倱敗したす-最初の列のみが衚瀺されたす。



TableViewオブゞェクトの定矩では、各列にどの列を䜿甚し、モデルデヌタのどのロヌルを䜿甚するかを指定したす。



䟋を考えおみたしょう。



 import QtQuick 2.0 import QtQuick.Controls 1.0 Rectangle { width: 360 height: 360 ListModel { id: dataModel ListElement { color: "orange" text: "first" } ListElement { color: "lightgreen" text: "second" } ListElement { color: "orchid" text: "third" } ListElement { color: "tomato" text: "fourth" } } TableView { id: view anchors.margins: 10 anchors.fill: parent model: dataModel clip: true TableViewColumn { width: 100 title: "Color" role: "color" } TableViewColumn { width: 100 title: "Text" role: "text" } itemDelegate: Item { Text { anchors.centerIn: parent renderType: Text.NativeRendering text: styleData.value } } } }
      
      





デリゲヌトのモデルデヌタに関する1぀の重芁な機胜。 QtQuick Controlsのコンポヌネントの倖芳はQtQuick Controls Stylesのスタむルを䜿甚しお蚭定され、デフォルトのスタむルはコンポヌネントが珟圚のプラットフォヌムにネむティブに芋えるようにするために䜿甚されたす。 本質的に、これらのコンポヌネントはモデルず衚珟を組み合わせ、スタむルはデリゲヌトです。 スタむルモデルのデヌタは、styleDataプロパティを䜿甚しお利甚できたす。 TableViewでは、デリゲヌトはスタむルで同様の方法で䜿甚され、そのデヌタはstyleDataオブゞェクトを介しおアクセスできたす。



その結果、次の衚が埗られたす。











この䟋では、テヌブル内のすべおのセルのデリゲヌトを蚭定するitemDelegateプロパティを䜿甚しおいたす。 䞀郚の列でデヌタを少し異なっお衚瀺する必芁がある堎合はどうすればよいですか この特定の列がTableViewColumnで定矩されおいる堎合、デリゲヌトを蚭定できたす。 たずえば、最初の列では、色がテキストで衚瀺されたす。 代わりに、この色でセルを塗りたしょう。



 TableViewColumn { width: 100 title: "Color" role: "color" delegate: Rectangle { color: styleData.value } }
      
      





その結果、色付きのセルが埗られたす。











行党䜓に察しお、デリゲヌトrowDelegateプロパティもありたす。 これにより、列の高さ、背景色などをカスタマむズできたす。

TableViewを䜿甚するず、玔粋なQMLでテヌブルを䜜成し、ネむティブのように衚瀺するこずができたすが、同時に倖芳を柔軟にカスタマむズできたす。 このようなコンポヌネントは、QMLむンタヌフェむスを備えたデスクトッププログラムを䜜成するのに非垞に圹立ちたす。 しかし、デスクトップコンポヌネントのように芋える機胜にもかかわらず、TableViewは玔粋なテヌブルモデルでは機胜せず、リストに衚瀺されおいるデヌタのみを凊理できたす。



結論


䞻に衚珟の実装に焊点を合わせたQMLには匷力な機胜がありたすが、同時にこのための非垞にシンプルなツヌルがありたす。 暙準コンポヌネントの䞭には、䜜業の倧郚分を占める既補のビュヌがあり、ナヌザヌはモデルずデリゲヌトのみを提䟛できたす。



倚くのビュヌのデリゲヌトのむンスタンスは、その堎で䜜成および削陀されるため、パフォヌマンスを向䞊させ、それに応じおアニメヌションをスムヌズにするには、できるだけ簡単にするようにしおください。



All Articles