Skip to main content
Salta al contingut

Vistes de llista

Una vista de llista pot ajudar-vos a mostrar amb facilitat molts components de forma dinàmica.

Les List views poden ajudar a mostrar objectes d'un model d'una manera atractiva. Per a utilitzar una vista de llista, haureu de realitzar un seguiment de tres coses:

  1. El model, el qual conté les dades que voleu mostrar a la vista de llista.
  2. El delegat, el qual defineix com es mostrarà cada element en el model.
  3. La vista de llista en si, la qual mostrarà la informació del model segons el delegat.

Per a més aclariments, la documentació de les Qt té una pàgina informativa sobre el tema.

Essencials de models i vistes

Una vista de llista té dues propietats essencials a les quals hem de parar atenció:

  • model, el qual accepta les dades o l'id de l'objecte que conté les dades
  • delegate, el qual accepta el component que utilitzarem per a mostrar les dades en el model

El model no és visible, ja que només conté dades. Normalment, el delegat s'embolcallarà en un Component perquè sigui reutilitzable: serveix com a esquema per a conèixer com instanciar cada delegat.

Aquí hi ha un exemple que conté exactament una vista de llista, un model i un delegat, utilitzant un 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`  }  }  } }

I el mateix exemple, en línia:

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`  }  }  } }

Entendre els models

El model conté les dades que s'utilitzaran per a emplenar la vista de llista. Les maneres diferents d'utilitzar els models tenen maneres diferents d'accedir a les dades:

MANERA D'UTILITZARCOM ACCEDIR-HIQUAN EMPRAR-HO
Models Qt amb més d'un rolmodel.index, model.someroleEn la majoria dels casos
Models Qt amb un rolmodel.index, model.somerole, model.modelDataEn la majoria dels casos, per a fer prototips
Model de matriu JavaScriptmodel.index, model.modelDataPer a fer prototips
Model entermodel.index, model.modelDataPer a fer prototips

Podeu llegir sobre altres maneres d'usar els models a la documentació de les Qt.

A la taula anterior, els «models Qt» es refereixen tant a models específics de C++ com QAbstractListModel i a models específics de QML com ListModel. Aquesta pàgina de la guia d'aprenentatge només se centrarà en models específics de QML. Més endavant, proporcionem una guia d'aprenentatge per a Connectar models C++ a QML utilitzant QAbstractListModel.

La propietat model.index es posa a disposició de cada model i conté l'índex (la posició) de cada delegat. Es pot escurçar a index per comoditat.

La propietat model.somerole esmentada anteriorment és només una variable de substitució, no és una propietat específica que prové del QML: somerole pot ser qualsevol rol que estigui definit pel model. En el primer exemple de codi d'aquesta pàgina que es mostra a sobre de la taula, el model plasmaProductsModel té els rols product i target, als quals es pot accedir amb model.product i model.target, respectivament.

De la mateixa manera que model.index es pot escurçar a index, cada propietat model.somerole es pot escurçar a només somerole (com product) per comoditat, però es recomana que es converteixin en propietats requerides:

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`  }  }  } }

A més, si el model conté només un rol o no té cap rol, també es pot accedir a les seves dades amb la propietat model.modelData, que també es pot escurçar a modelData (i com a tal també necessitaria ser una propietat requerida):

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 // Aquest coincideix amb model.software  }  }  } }

Com a comparació, aquí és com es veuria el codi anterior amb una matriu JavaScript, sense rol:

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  }  }  } }

L'ús d'un enter per al model pot ser útil per a casos molt específics, com el prototipatge i les proves:

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}`  }  }  } }

Entendre les vistes i els delegats

Tornem a l'exemple original:

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 diferència del model (que només conté dades) i d'un delegat Component (que només apareixen quan s'instancien), la vista és un component visual instanciat immediatament i, per tant, necessita tenir les seves dimensions establertes o utilitzar ancoratges o disposicions.

Com que les vistes són normalment llistes de contingut per les quals l'usuari es desplaçarà, quan s'afegeixen a un Kirigami.ScrollablePage, les vistes es converteixen en el contingut principal amb poc farciment al voltant d'elles, i no hi ha cap necessitat de fer que ompli la pàgina. Quan la vista s'afegeix a una única Kirigami.Page, necessitarà establir les seves dimensions correctament abans que aparegui. En altres paraules: a la pàgina desplaçable de dalt, no es requereix anchors.fill: parent; si s'utilitzés una única pàgina, seria necessària.

Hi ha diverses API de vistes que es poden utilitzar, algunes de les Qt i altres de Kirigami. A continuació us detallem les més utilitzades:

D'altra banda, el delegat sempre ha de tenir les seves dimensions establertes. Generalment, les seves dimensions s'estableixen per a utilitzar només l'amplada completa de la vista.

L'ús més comú d'un delegat es troba dins d'un Component, que no instancia el delegat immediatament. Quan es construeix una vista, el delegat s'utilitza com a esquema per a fer cada element a la vista.

Tot i que podeu crear els vostres propis components personalitzats per a ser utilitzats com a delegats sense les API de les Qt específiques de delegats (per exemple, una disposició que conté alguns elements), els QtQuick Controls proporcionen les API de delegats que són més senzilles d'utilitzar:

Hauríeu de preferir utilitzar els delegats originals de les Qt quan sigui possible.

A sobre d'aquests delegats de les Qt, el Kirigami proporciona els seus propis equivalents, amb la funcionalitat afegida de subtítols i icones:

L'API que acaba amb «Delegate» es pot definir com un delegat directe de la vista, igual que els exemples anteriors que utilitzaven 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"  }  }  } }

Tant TitleSubtitle com IconTitleSubtitle s'espera que s'utilitzin per a substituir el «contentItem» d'un delegat de les Qt, per exemple:

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"  }  }  }  } }

Es pot veure un exemple pràctic d'ús dels delegats del Kirigami al fitxer ListItemTest al repositori del Kirigami.