Zobrazenia zoznamov
Komponenty Kirigami.Chip sú malé prvky zdedené z AbstractButton používané na zobrazenie bežných vlastností alebo filtrov niečoho. Typicky ide o textové prvky, ktoré sú tiež interaktívne a majú voliteľné tlačidlo na vymazanie.
- Čipy možno jednoducho pridať pomocou komponentu Kirigami.Chip. Priradením reťazca do zdedeného poľa AbstractButton.text dáme čipom ich názov.
- Keďže čipy sú určené na viacnásobné použitie, pravdepodobne budete chcieť použiť nejaký druh zoznamovej dátovej štruktúry a iterovať cez ne na zobrazenie čipov. Na to potrebujeme komponent ListModel a Repeater.
- ListModel sa používa ako úložisko pre čipy. Na naplnenie ListModel (a teda čipov) deklarujeme niekoľko komponentov ListElement, ktoré obsahujú pole známe ako
text. Tento reťazec priradený odtiaľto do poľatextmôžeme použiť pre každý opakovaný čip.
Repeater sa používa na zobrazovanie čipov. Najprv musíme nastaviť pole model Repeatera na náš ListModel alebo vytvoriť ListModel vo vnútri repeatera. Potom deklarujeme komponent Kirigami.Chip vo vnútri Repeatera a priradíme jeho pole text s dátami prvku pomocou vlastnosti modelData.
Základy modelov a zobrazení
Dáta do ListModel môžete dynamicky pridávať a odstraňovať a Repeater automaticky tieto zmeny vykoná. Avšak jednoduchá zmena konkrétnej položky buď z Repeatera alebo ListModel neovplyvní druhý a vyžaduje zmenu oboch, pokiaľ sa nepoužije niečo ako QAbstractListModel. Viac informácií nájdete v Príkladovej aplikácii.
- Nasledujúca príkladová aplikácia ukazuje, ako možno čipy použiť v programoch ako sú zoznamy úloh.
- Urobte vaše aplikácie interaktívnejšie pomocou tlačidiel, ovládacích prvkov výberu, posuvníkov a textových polí.
Kirigami využíva široký výber rôznych interaktívnych prvkov z Qt, ktoré môžete použiť vo vašich aplikáciách. Každý typ má mierne odlišné interakčné štýly, vizuálne štýly a funkčnosť. Použitie správneho typu ovládacieho prvku vo vašej aplikácii môže pomôcť urobiť vaše používateľské rozhranie responzívnejšie a intuitívnejšie.
V aplikáciách Kirigami používame Button z QtQuick Controls. Ich používanie je celkom jednoduché: nastavíme vlastnosť text a akúkoľvek akciu, ktorú chceme, aby vykonali, nastavíme na vlastnosť onClicked.
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`
}
}
}
}A ten istý príklad, inline:
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`
}
}
}
}Upozornenie
Model obsahuje dáta, ktoré sa použijú na naplnenie zobrazenia zoznamu. Rôzne spôsoby použitia modelov majú rôzne spôsoby prístupu k dátam:
| SPÔSOB POUŽITIA | AKO PRISTUPOVAŤ | KEDY POUŽIŤ |
|---|---|---|
| Qt modely s viac ako jednou rolou | model.index, model.somerole | Vo väčšine prípadov |
| Qt modely s jednou rolou | model.index, model.somerole, model.modelData | Vo väčšine prípadov, na prototypovanie |
| Model poľa JavaScript | model.index, model.modelData | Na prototypovanie |
| Celočíselný model | model.index, model.modelData | Na prototypovanie |
O ďalších spôsoboch použitia modelov si môžete prečítať v dokumentácii Qt.
V tabuľke vyššie sa "Qt modely" vzťahujú na modely špecifické pre C++ ako QAbstractListModel aj na modely špecifické pre QML ako ListModel. Táto stránka tutoriálu sa zameria iba na modely špecifické pre QML. Ďalej poskytujeme tutoriál na Pripojenie C++ modelov k QML pomocou QAbstractListModel.
Vlastnosť model.index je dostupná pre každý model a obsahuje index (pozíciu) každého delegáta. Pre pohodlie sa dá skrátiť na index.
Vlastnosť model.somerole uvedená vyššie je len zástupný symbol, nie je to špecifická vlastnosť pochádzajúca z QML: somerole môže byť akákoľvek rola definovaná modelom. V prvom príklade kódu na tejto stránke zobrazenom nad tabuľkou má model plasmaProductsModel role product a target, ku ktorým je možné pristupovať pomocou model.product a model.target.
Rovnako ako sa model.index dá skrátiť na index, každá vlastnosť model.somerole sa dá skrátiť len na somerole (ako product) pre pohodlie, ale odporúča sa, aby boli zmenené na vyžadované vlastnosti:
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`
}
}
}
}Navyše, ak model obsahuje iba jednu rolu alebo nemá žiadnu rolu, k jeho dátam je možné pristupovať aj pomocou vlastnosti model.modelData, ktorá sa dá tiež skrátiť na modelData (a preto by tiež musela byť vyžadovanou vlastnosťou):
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 // Toto zodpovedá model.software
}
}
}
}Pre porovnanie, takto by vyzeral vyššie uvedený kód s poľom JavaScript, bez role:
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
}
}
}
}Použitie celého čísla pre model môže byť užitočné pre veľmi špecifické prípady, konkrétne prototypovanie a testy:
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}`
}
}
}
}Pochopenie zobrazení a delegátov
Vráťme sa k pôvodnému príkladu:
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`
}
}
}
}Na rozdiel od modelu (ktorý iba obsahuje dáta) a delegátového Component (ktorý sa zobrazí iba pri vytvorení inštancie), zobrazenie je vizuálny komponent okamžite vytvorený, a preto musí mať buď nastavené rozmery, alebo používať kotvy alebo rozloženia.
Keďže zobrazenia sú bežne zoznamy obsahu, cez ktoré chce používateľ posúvať, keď sa pridajú na Kirigami.ScrollablePage, zobrazenia sa stanú hlavným obsahom s malým odsadením okolo nich a nie je potrebné, aby vyplnili stránku. Keď sa zobrazenie pridá na jednoduchú Kirigami.Page, bude vyžadovať správne nastavenie rozmerov predtým, než sa zobrazí. Inými slovami: v posúvateľnej stránke vyššie nie je anchors.fill: parent vyžadované; ak by bola použitá jednoduchá stránka, bolo by vyžadované.
Existuje viacero API zobrazení, ktoré sa dajú použiť, niektoré z Qt a niektoré z Kirigami. Tu sú najčastejšie používané:
- ListView od Qt
- GridView od Qt
- TableView od Qt
- TreeView od Qt
- CardsListView od Kirigami
- ColumnView od Kirigami
Delegát na druhej strane vždy potrebuje mať nastavené svoje rozmery. Zvyčajne sú jeho rozmery nastavené na použitie iba celej šírky zobrazenia.
Bežné chyby
Vyššie uvedené znamená, že delegáty by nemali mať spodné kotvy, pretože delegát nemusí mať rovnakú výšku ako zobrazenie. Inými slovami, pravdepodobne nikdy nebudete chcieť použiť anchors.fill: parent.
Navyše, hoci je možné nastaviť jeho rozmery pomocou rodičovského prvku a kotiev, čo je zvyčajne contentItem zobrazenia, takto:
Controls.ItemDelegate {
anchors.left: parent.left
anchors.right: parent.right
text: // ...
}Nie je zaručené, že rodičom delegáta bude zobrazenie, a preto by sa tomu malo vyhnúť. Namiesto toho použite pripojenú vlastnosť ListView.view na odkázanie na rodičovské zobrazenie delegáta:
Controls.ItemDelegate {
width: ListView.view.width
text: // ...
}Najčastejšie použitie delegáta je v rámci Component, ktorý nevytvára inštanciu delegáta okamžite. Keď sa zobrazenie skonštruuje, delegát sa potom použije ako plán na vytvorenie každej položky v zobrazení.
Hoci si môžete vytvoriť vlastné komponenty na použitie ako delegáty bez API delegátov špecifických pre Qt (napríklad Layout obsahujúci niekoľko Items), QtQuick Controls poskytuje API delegátov, ktoré sú jednoduchšie na použitie:
- ItemDelegate (delegáty iba s textom)
- CheckDelegate (delegáty so zaškrtávacím políčkom)
- RadioDelegate (delegáty s prepínačom)
- SwitchDelegate (delegáty s prepínačom)
- SwipeDelegate (delegáty, ktoré sa dajú posunúť)
Mali by ste uprednostniť použitie pôvodných Qt delegátov, kde je to možné.
Popri týchto Qt delegátoch poskytuje Kirigami svoje vlastné ekvivalenty s pridanou funkčnosťou podtitulov a ikon:
- TitleSubtitle
- IconTitleSubtitle
- SubtitleDelegate
- CheckSubtitleDelegate
- RadioSubtitleDelegate
- SwitchSubtitleDelegate
API končiace na "Delegate" sa dá nastaviť ako priamy delegát zobrazenia, rovnako ako predchádzajúce príklady, ktoré používali 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"
}
}
}
}Obidva TitleSubtitle a IconTitleSubtitle sú určené na použitie na prepísanie contentItem Qt delegáta, napríklad:
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 {
// 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}.`
contentItem: KD.IconTitleSubtitle {
title: parent.text
subtitle: `This delegate is stored at index ${model.index} of this list`
icon.name: "kde"
}
}
}
}
}Praktický príklad použitia delegátov Kirigami je viditeľný v súbore ListItemTest v repozitári Kirigami.