Disposicions (Layout), vistes de llista (ListView) i targetes (Card)
Dissenyar el contingut
Ara que entenem com funcionen les pàgines, és hora d'afegir-hi coses. Repassarem una sèrie de components i elements de disposició importants que seran útils en dissenyar la nostra aplicació.
Al final d'aquesta secció tindreu una aplicació d'aspecte polit.
Vistes de llista (ListView)
Si heu emprat alguna vegada el Discover, el NeoChat o l'Arranjament del sistema del Plasma, us haureu trobat amb una ListView. En poques paraules, les vistes de llista permeten mostrar les dades en una llista.
pageStack.initialPage: Kirigami.ScrollablePage {
// ...
Kirigami.CardsListView {
id: cardsView
model: kountdownModel
delegate: kountdownDelegate
}
}Això sembla críptic, però no us preocupeu. Comencem des del principi.
Ara afegirem aquest component dins del nostre Kirigami.ScrollablePage de la darrera guia d'aprenentatge.
We're using Kirigami.CardsListView, which is a ListView that allows us to easily display cards in a list. However, ListViews are made to show data taken from a model - to automatically populate itself from a set of data that we point it to. That's where the model property comes in: in this example, it's pointing to kountdownModel.
Model
Kirigami.ApplicationWindow {
// ...
ListModel {
id: kountdownModel
// Cada ListElement és un element en la llista que conté informació
ListElement {
name: "Dog birthday!!"
description: "Big doggo birthday blowout."
date: 100
}
}
// ...
}Afegirem el kountdownModel dins de la Kirigami.ApplicationWindow de la darrera guia d'aprenentatge.
Un model defineix la manera en què s'estructura una entrada de dades. Per ara, el nostre kountdownModel només consistirà d'un element. Si mirem el nostre ListElement anterior, veurem com s'estructuren els elements del kountdownModel: conté un nom, una descripció i una data. Això no és immutable, i podeu tenir diversos tipus de dades en el vostre model. Els dos primers són cadenes i el tercer és un número que utilitzem com a marcador de posició.
Nota
Com que el QML està construït sobre el JavaScript, moltes de les característiques d'aquest llenguatge estan disponibles per al seu ús en fitxers QML. No obstant això, les variables QML s'han de prefixar ambproperty, a menys que estigui dins d'un bloc de codi JS. Podeu llegir-ne més en aquesta pàgina.Els models també són útils perquè es poden modificar mitjançant l'ús de diversos mètodes. Alguns importants són:
- ListModel.append(yourobject: jsobject) afegeix un objecte de JavaScript (JSObject)
yourobjectal ListModel, i el col·loca després de l'últim element del model. Perquè això succeeixi correctament, cal proporcionar un objecte JSObject amb les propietats correctes i els tipus de dades corresponents. - ListModel.get(index: int) retorna el JSObject en la ubicació de l'índex que heu proporcionat.
- ListModel.remove(index: int, count: int) elimina el JSObject en la ubicació proporcionada
index, i tantes com vulgueu després d'aquesta ubicació de l'índex com indiqueu acount(1 només inclou el JSObject a l'índex proporcionat). - ListModel.set(index: int, yourobject: jsobject) canvia l'element en la ubicació proporcionada de
indexamb els valors proporcionats ayourobject. Les mateixes regles que amb.append().
Delegats
Mentre que kountdownModel conté les dades que es mostraran, el nostre kountdownDelegate gestionarà com es mostraran les dades a la ListView. Per això farem servir una Kirigami.CardsListView dissenyada per a mostrar delegats del tipus targetes i aquests delegats es representaran visualment per mitjà d'una Kirigami.AbstractCard.
Delegates automatically receive the properties of the ListElement instances that we have specified in our model. We can therefore just refer to their name, description, and date properties as if they were conventional variables within our delegate.
Construir la targeta de delegat
El Component que representarà el nostre delegat es pot afegir dins del nostre Kirigami.ApplicationWindow. Després comprovarem que fa cada part del nostre component delegat.
Kirigami.ApplicationWindow {
// ...
Component {
id: kountdownDelegate
Kirigami.AbstractCard {
contentItem: Item {
// implicitWidth/Height defineix l'amplada/alçada natural d'un element si no se
// n'especifica cap. La configuració següent defineix la mida preferida d'un
// component en funció del seu contingut.
implicitWidth: delegateLayout.implicitWidth
implicitHeight: delegateLayout.implicitHeight
GridLayout {
id: delegateLayout
anchors {
left: parent.left
top: parent.top
right: parent.right
}
rowSpacing: Kirigami.Units.largeSpacing
columnSpacing: Kirigami.Units.largeSpacing
columns: root.wideScreen ? 4 : 2
Kirigami.Heading {
level: 1
text: date
}
ColumnLayout {
Kirigami.Heading {
Layout.fillWidth: true
level: 2
text: name
}
Kirigami.Separator {
Layout.fillWidth: true
visible: description.length > 0
}
Controls.Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: description
visible: description.length > 0
}
}
Controls.Button {
Layout.alignment: Qt.AlignRight
Layout.columnSpan: 2
text: i18n("Edit")
// onClicked: s'ha de fer... aviat!
}
}
}
}
}
// ...
}implicitWidth i implicitHeight
A la primera part donarem un cop d'ull a com gestionar l'amplada i l'alçada del nostre component:
Kirigami.AbstractCard {
contentItem: Item {
implicitWidth: delegateLayout.implicitWidth
implicitHeight: delegateLayout.implicitHeight
GridLayout {
id: delegateLayout
// ...
}
}
}Looking at our Kirigami.AbstractCard, the first properties we set are implicitWidth and implicitHeight. We have set these to the delegateLayout.implicitWidth and delegateLayout.implicitHeight, i.e. the implicitWidth and implicitHeight of the GridLayout element.
Les amplades i alçades implícites són propietats disponibles en qualsevol Item que funcionen com a consells i s'estableixen com a valor predeterminat, o com a reserva, si no hi ha una amplada o alçada explícita establerta per a aquests components. Aquests valors són predeterminats a 0x0, per tant, és molt important que els definiu en components Item en brut tal com s'ha fet anteriorment.
Aquí haurem establert la implicitWidth i implicitHeight de la nostra Kirigami.AbstractCard a la de la GridLayout següent per a assegurar-nos que no desbordi la targeta. D'aquesta manera, la targeta pren tant espai com sigui necessari per al seu contingut.
Disposicions
La GridLayout es troba dins del component Item que hem proporcionat per a la propietat contentItem. Aquest és l'Item que conté el que es mostrarà a la targeta.
També haurem de triar una disposició «layout» per als nostres components, de manera que no s'apilin un damunt de l'altre. Hi ha tres tipus principals entre les quals podem triar:
- ColumnLayout distribueix els components verticalment, en una sola columna
- RowLayout distribueix els components horitzontalment, en una sola fila
- GridLayout distribueix els components en una quadrícula amb una composició de la vostra elecció
Amb ColumnLayout i RowLayout, tot el que hem de fer és escriure els nostres components dins del component «Layout». Com podeu veure, hem optat per una GridLayout, la qual implica una mica més de treball manual.
GridLayout {
id: delegateLayout
anchors {
left: parent.left
top: parent.top
right: parent.right
}
rowSpacing: Kirigami.Units.largeSpacing
columnSpacing: Kirigami.Units.largeSpacing
columns: root.wideScreen ? 4 : 2
// ...
}El primer que veieu és anchors. El sistema d'ancoratge de QtQuick proporciona una forma útil d'assegurar-vos que els components estiguin col·locats en certes parts d'un component pare. Hem ancorat la nostra GridLayout a l'esquerra, a dalt i a la dreta de la targeta principal, assegurant que el nostre contingut s'estengui per tota la targeta.
Next we specify the spacing between the rows and columns within our grid, so that our components don't bunch up. Kirigami provides a number of handy predefined units to use for this purpose:
| Unitat de Kirigami | Píxels |
|---|---|
| smallSpacing | 4px |
| largeSpacing | 8px |
| gridUnit | 18px |
Nota
El Grup de Disseny Visual de KDE (VDG) té molta més informació sobre les diferents unitats definides en el Plasma i el Kirigami a les Directrius d'interfície humana.As you might remember, root is the id of our Kirigami.ApplicationWindow. It provides the wideScreen property, used to determine whether the current device screen is a widescreen (i.e. a computer monitor or a phone in landscape). We use a ternary conditional here to vary the number of columns in our grid depending on the screen we are using: if it's a widescreen, the grid will have 4 columns, else it will have 2.
Components interns
Podríem crear tres etiquetes dins del nostre component delegat i cridar-les un dia. Però això no es veuria particularment bonic. Farem ús d'alguns components més adequats:
GridLayout {
// ...
Kirigami.Heading {
Layout.fillHeight: true
level: 1
text: date
}
ColumnLayout {
Kirigami.Heading {
Layout.fillWidth: true
level: 2
text: name
}
Kirigami.Separator {
Layout.fillWidth: true
visible: description.length > 0
}
Controls.Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: description
visible: description.length > 0
}
}
Controls.Button {
Layout.alignment: Qt.AlignRight
Layout.columnSpan: 2
text: i18n("Edit")
}
}
Com es veu la targeta personalitzada
- Left, Kirigami.Heading: uses the
ListElement'sdateas a level 1 heading. - Middle, ColumnLayout: has a Kirigami.Heading that displays the task name; a Kirigami.Separator, which provides the horizontal line; and a Controls.Label, that displays a task's optional description. The latter two components have a visible property, which checks if the description is empty or not and displays the components depending on the result of
description.length > 0. - A la dreta, Controls.Button: un botó que farà alguna cosa... aviat!
La nostra aplicació fins ara
Main.qml:
| |

Així que aquí està la nostra targeta bàsica!
Amb aquests passos, hem establert les bases bàsiques per a afegir tota la funcionalitat a la nostra aplicació.