Listo vidoj
Listviews povas helpi vin montri objektojn de modelo en alloga maniero. Por uzi listvidon, vi devas observi tri aferojn:
- La modelo, kiu enhavas la datumojn, kiujn vi volas ke via listvido montru
- La delegito, kiu difinas kiel ĉiu elemento en la modelo estos montrata
- La listvido mem, kiu montros informojn el la modelo laŭ la delegito
Se vi ŝatus plian klarigon, la Qt-dokumentaro havas informan paĝon pri la temo.
Esencaj de modeloj kaj vidoj
Listvido havas du esencajn ecojn, pri kiuj ni devas atenti:
- modelo, kiu akceptas la datumojn aŭ la
id
de la objekto kiu tenas la datumojn - delegito, kiu akceptas la komponanton, kiun ni uzos por montri la datumojn en la modelo
La modelo ne estas videbla, ĉar ĝi enhavas nur datumojn. Tipe la delegito estos envolvita en Komponento tiel ke ĝi estas reuzebla: ĝi servas kiel skizo por kiel ekzempligi ĉiun delegiton.
Jen ekzemplo kiu enhavas precize unu listvidon, unu modelon kaj unu delegiton, uzante Kirigami.SubtitleDelegate:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "List of Plasma products"
width: 600
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
anchors.fill: parent
model: plasmaProductsModel
delegate: listDelegate
}
ListModel {
id: plasmaProductsModel
ListElement { product: "Plasma Desktop"; target: "desktop" }
ListElement { product: "Plasma Mobile"; target: "mobile" }
ListElement { product: "Plasma Bigscreen"; target: "TVs" }
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
text: `${model.product} is KDE software developed for ${model.target} stored at index ${model.index} of this list`
}
}
}
}
Kaj la ĝusta sama ekzemplo, enlinia:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "List of Plasma products (inline)"
width: 600
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
anchors.fill: parent
model: ListModel {
id: plasmaProductsModel
ListElement { product: "Plasma Desktop"; target: "desktop" }
ListElement { product: "Plasma Mobile"; target: "mobile" }
ListElement { product: "Plasma Bigscreen"; target: "TVs" }
}
delegate: Controls.ItemDelegate {
width: ListView.view.width
text: `${model.product} is KDE software developed for ${model.target} stored at index ${model.index} of this list`
}
}
}
}
Kompreni modelojn
La modelo enhavas la datumojn, kiuj estos uzataj por plenigi la listvidon. Malsamaj manieroj uzi modelojn havas malsamajn manierojn aliri la datumojn:
VOJ DE UZINO | KIEL ALIRI | KIAM UZI |
---|---|---|
Qt-modeloj kun pli ol unu rolo | model.index, model.somerole | Plej ofte |
Qt-modeloj kun unu rolo | model.index, model.somerole, model.modelData | Plejofte, por prototipado |
JavaScript tabelmodelo | model.index, model.modelData | Por prototipado |
Entjera modelo | model.index, model.modelData | Por prototipado |
Vi povas legi pri aliaj manieroj uzi modelojn en la Qt-dokumentado.
En la supra tabelo, "Qt-modeloj" rilatas al ambaŭ C++-specifaj modeloj kiel QAbstractListModel kaj QML-specifaj modeloj kiel ListModel. Ĉi tiu lernilo-paĝo nur koncentriĝos pri QML-specifaj modeloj. Pli antaŭen ni provizas lernilon por Konekti C++-modelojn al QML uzante QAbstractListModel.
La propreco model.index
estas disponebla por ĉiu modelo kaj enhavas la indekson (la pozicion) de ĉiu delegito. Ĝi povas esti mallongigita al indekso
por oportuno.
La eco model.somerole
menciita supre estas nur lokokupilo, ĝi ne estas specifa eco kiu venas de QML: somerole
povas esti ajna rolo kiu estas difinita de la modelo. En la unua kodekzemplo de ĉi tiu paĝo montrita super la tabelo, la modelo plasmaProductsModel
havas la rolojn produkto
kaj celo
, kiuj estas alireblaj per model.product
kaj model.target
, respektive.
Same kiel model.index
povas esti mallongigita al index
, ĉiu model.somerole
propreco povas esti mallongigita al nur somerole
(kiel produkto
) por oportuno, sed estas rekomendite ke ili estu igitaj postulataj trajtoj:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "List of Plasma products (shortened with required properties)"
width: 600
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
anchors.fill: parent
model: plasmaProductsModel
delegate: listDelegate
}
ListModel {
id: plasmaProductsModel
ListElement { product: "Plasma Desktop"; target: "desktop" }
ListElement { product: "Plasma Mobile"; target: "mobile" }
ListElement { product: "Plasma Bigscreen"; target: "TVs" }
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
required property string product
required property string target
required property int index
text: `${product} is KDE software developed for ${target} stored at index ${index} of this list`
}
}
}
}
Aldone, se la modelo enhavas nur unu rolon aŭ tute ne havas rolon, ĝiaj datumoj ankaŭ estas alireblaj per la propreco model.modelData
, kiu ankaŭ povas esti mallongigita al modelData
(kaj kiel tia ankaŭ bezonus esti postulata propreco):
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "List of KDE software"
width: 400
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
anchors.fill: parent
model: kdeSoftwareModel
delegate: listDelegate
}
ListModel {
id: kdeSoftwareModel
ListElement { software: "Dolphin" }
ListElement { software: "Discover" }
ListElement { software: "KHelpCenter" }
ListElement { software: "KCalc" }
ListElement { software: "Ark" }
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
required property string modelData
text: modelData // Ĉi tio kongruas kun modelo.softvaro
}
}
}
}
Por komparo, jen kiel la supra kodo aspektus kun JavaScript-tabelo, sen rolo:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "List of KDE software (as JS array)"
width: 400
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
anchors.fill: parent
model: ["Dolphin", "Discover", "KHelpCenter", "KCalc", "Ark"]
delegate: listDelegate
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
required property string modelData
text: modelData
}
}
}
}
Uzi entjeron por la modelo povas esti utila por tre specifaj kazoj, nome prototipado kaj testoj:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "Simple list of indexes"
width: 400
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
anchors.fill: parent
model: 30
delegate: listDelegate
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
required property string modelData
text: `This delegate's index is: ${modelData}`
}
}
}
}
Komprenante vidojn kaj delegitojn
Ni reiru al la originala ekzemplo:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
title: "List of Plasma products"
width: 600
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
// ankroj.plenigi: patro
model: plasmaProductsModel
delegate: listDelegate
}
ListModel {
id: plasmaProductsModel
ListElement { product: "Plasma Desktop"; target: "desktop" }
ListElement { product: "Plasma Mobile"; target: "mobile" }
ListElement { product: "Plasma Bigscreen"; target: "TVs" }
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
text: `${model.product} is KDE software developed for ${model.target} stored at index ${model.index} of this list`
}
}
}
}
Male al la modelo (kiu nur enhavas datenojn) kaj delegito Komponento (kiu nur aperas kiam instancigita), la vido estas vida komponanto tuj instancigita kaj do ĝi devas aŭ havi siajn dimensiojn agordita aŭ uzu ankrojn aŭ Aranĝojn.
Ĉar vidoj estas ofte listoj de enhavo, la uzanto volus rulumi, kiam ili estas aldonitaj al Kirigami.ScrollablePage, vidoj iĝas la ĉefa enhavo kun malmulte da kompletigo ĉirkaŭ ili, kaj ne necesas. por ke ĝi plenigu la paĝon. Kiam la vido estas aldonita al simpla Kirigami.Paĝo, ĝi postulos ĝuste agordi ĝiajn dimensiojn antaŭ ol ĝi aperos. Alivorte: en la rulebla paĝo supre, anchors.fill: parent
ne estas bezonata; se oni uzus simplan paĝon, ĝi estus postulata.
Estas pluraj vidoj API-oj uzeblaj, iuj de Qt kaj iuj de Kirigami. Jen la plej ofte uzataj:
- [ListView] de Qt (docs:qtquick;QtQuick.ListView)
- [GridView] de Qt (docs:qtquick;QtQuick.GridView)
- [TableView] de Qt (docs:qtquick;QtQuick.TableView)
- [TreeView] de Qt (docs:qtquick;QtQuick.TreeView)
- [CardsListView] de Kirigami (docs:kirigami2;CardsListView)
- [ColumnView] de Kirigami (docs:kirigami2;ColumnView)
La delegito aliflanke ĉiam bezonas havi siajn dimensiojn fiksitaj. Ĝenerale ĝiaj dimensioj estas agordita por uzi nur la plenan larĝon de la vido.
Oftaj eraroj
Ĉi-supra signifas, ke delegitoj ne havu malsuprajn ankrojn, ĉar la delegito ne bezonas havi la saman altecon kiel la vido. Alivorte, vi verŝajne neniam volos uzi ankroj.fill: parent
.
Aldone, kvankam eblas agordi ĝiajn dimensiojn uzante la gepatron kaj ankrojn, kiu kutime estas la enhavo de la vido, tiel:
Controls.ItemDelegate {
anchors.left: parent.left
anchors.right: parent.right
text: // ...
}
Ne estas garantiite ke la gepatro de la delegito estos vido, kaj do ĝi devus esti evitita. Anstataŭe, uzu la ListView.view kunan proprecon por montri la gepatran vidon de la delegito:
Controls.ItemDelegate {
width: ListView.view.width
text: // ...
}
La plej ofta uzo de delegito estas ene de Component, kiu ne instantiigas la delegiton tuj. Kiam vido estas konstruita, la delegito tiam estas utiligita kiel skizo por fari ĉiun objekton en la vido.
Dum vi povas fari viajn proprajn proprajn komponantojn por esti uzataj kiel delegitoj sen delegitaj specifaj Qt-API-oj (ekzemple, Aranĝo enhavanta kelkajn Erojn), QtQuick Controls disponigas delegitajn API-ojn pli simplajn uzeblajn:
- ItemDelegate (delegitoj kun nur teksto)
- CheckDelegate (delegitoj kun markobutono)
- RadioDelegate (delegitoj kun radio)
- SwitchDelegate (delegitoj kun ŝaltilo)
- SwipeDelegate (delegitoj, kiujn oni povas svingi)
Vi devus preferi uzi la kontraŭfluajn Qt-delegitojn kie eblas.
Aldone al ĉi tiuj Qt-delegitoj, Kirigami disponigas siajn proprajn ekvivalentojn, kun la aldonita funkcieco de subtekstoj kaj piktogramoj:
- TitleSubtitle
- IconTitleSubtitle
- SubtitoloDelegito
- CheckSubtitleDelegate
- RadioSubtitoloDelegito
- SwitchSubtitleDelegate
La API finiĝanta per "Delegito" povas esti agordita kiel rekta delegito de la vido, same kiel la antaŭaj ekzemploj, kiuj uzis Controls.ItemDelegate:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
import org.kde.kirigami.delegates as KD
Kirigami.ApplicationWindow {
title: "List of Plasma products"
width: 600
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
model: plasmaProductsModel
delegate: listDelegate
}
ListModel {
id: plasmaProductsModel
ListElement { product: "Plasma Desktop"; target: "desktop" }
ListElement { product: "Plasma Mobile"; target: "mobile" }
ListElement { product: "Plasma Bigscreen"; target: "TVs" }
}
Component {
id: listDelegate
KD.CheckSubtitleDelegate {
width: ListView.view.width
text: `${model.product} is KDE software developed for ${model.target}.`
subtitle: `This delegate is stored at index ${model.index} of this list`
icon.name: "kde"
}
}
}
}
Kaj TitleSubtitle kaj IconTitleSubtitle estas atenditaj esti uzataj por superregi la enhavoItem de Qt-delegito, ekzemple:
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
import org.kde.kirigami.delegates as KD
Kirigami.ApplicationWindow {
title: "List of Plasma products"
width: 600
height: 400
pageStack.initialPage: Kirigami.ScrollablePage {
ListView {
// ankroj.plenigi: patro
model: plasmaProductsModel
delegate: listDelegate
}
ListModel {
id: plasmaProductsModel
ListElement { product: "Plasma Desktop"; target: "desktop" }
ListElement { product: "Plasma Mobile"; target: "mobile" }
ListElement { product: "Plasma Bigscreen"; target: "TVs" }
}
Component {
id: listDelegate
Controls.ItemDelegate {
width: ListView.view.width
text: `${model.product} is KDE software developed for ${model.target}.`
contentItem: KD.IconTitleSubtitle {
title: parent.text
subtitle: `This delegate is stored at index ${model.index} of this list`
icon.name: "kde"
}
}
}
}
}
Praktika ekzemplo pri uzado de Kirigami-delegitoj povas esti vidita en la ListItemTest-dosiero en la Kirigami Deponejo.