Aranĝoj, ListViews kaj Kartoj

Eltrovi la malsamajn manierojn meti aferojn sur paĝon

Disponi vian enhavon

Now that we understand how pages work, it is time to add stuff to them. We will be going through a number of important layout components and elements that will be useful when designing our app.

By the end of this section you'll have a neat-looking app.

ListViews

Se vi iam uzis Discover, NeoChat, aŭ la Sistemajn Agordojn de Plasma, vi havos trovi ListView. Tute simple, ĝi ebligas al vi montri datumojn en listo.

Kirigami.CardsListView {
    id: cardsView
    model: kountdownModel
    delegate: kountdownDelegate
}

Tio ŝajnas kripta, sed ne maltrankviliĝu. Ni komencu de la komenco.

Ni aldonas ĉi tiun komponanton ene de nia Kirigami.ScrollablePage de la lasta lernilo.

Ni uzas Kirigami.CardsListView , kiu estas ListView kiu ebligas al ni facile montri kartojn en listo. Tamen, ListViews estas faritaj por montri datumojn prenitajn de modelo - por aŭtomate plenigi sin de aro de datumoj al kiuj ni montras ĝin. Jen kie la propreco modelo eniras: en ĉi tiu ekzemplo, ĝi montras al kountdownModel.

Modelo

ListModel {
    id: kountdownModel
    // Ĉiu ListElement estas elemento en la listo, enhavante informojn
    ListElement {
        name: "Dog birthday!!"
        description: "Big doggo birthday blowout."
        date: 100
    }
}

We add our kountdownModel inside the Kirigami.ApplicationWindow from the last tutorial.

Modelo difinas la manieron kiel dateneniro estas strukturita. Nia countdownModel konsistos el nur unu elemento nuntempe. Rigardante nian ListElement supre, ni povas vidi kiel la datumoj de nia kountdownModel estas strukturitaj: ĝi enhavas nomo, priskribo kaj dato. Ĉi tio ne estas fiksita, kaj vi eble havas malsamajn specojn de datumoj en via modelo. La unuaj du estas nur ĉenoj, kaj la tria estas nombro, kiun ni uzas kiel anstataŭilon.

Modeloj ankaŭ estas utilaj en kiel ili povas esti modifitaj per la uzo de pluraj metodoj. Iuj gravaj estas:

Delegates

While our kountdownModel contains the data that will be displayed, our kountdownDelegate will handle how the data will be displayed in the ListView. For that we use a Kirigami.CardsListView designed to display card-type delegates, and those delegates will be visually represented by means of a Kirigami.AbstractCard .

Delegates automatically receive the properties of the ListElements 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.

Building the delegate card

The Component that will represent our delegate can be added inside our Kirigami.ApplicationWindow . We will then check what each part of our delegate component does.

Component {
    id: kountdownDelegate
    Kirigami.AbstractCard {
        contentItem: Item {
            // implicitWidth/Height difinas la naturan larĝon/alton de ero se neniu larĝo aŭ alteco
            // estas specifita. La suba agordo difinas la preferatan grandecon de komponento laŭ ĝia
            // enhavo
            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 {
                    Layout.fillHeight: true
                    level: 1
                    text: (date < 100000) ? date : i18n("%1 days", Math.round((date-Date.now())/86400000))
                }

                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")
                    // onKlakita: farota... baldaŭ!
                }
            }
        }
    }
}

implicitWidth kaj implicitHeight

La unua parto, kiun ni rigardos, estas kiel administri la larĝon kaj altecon de nia komponanto:

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.

Implicit widths and heights are properties available in any Item that function as hints and are set as a default, or as a fallback, if there is no explicit width or height set for these components. These values default to 0x0, so it is very important that you define those in raw Item components as done above.

Here we have set the implicitWidth and implicitHeight of our Kirigami.AbstractCard to that of the GridLayout below to ensure it does not spill out of the card. This way, the card takes as much space is necessary for its contents.

Aranĝoj

La GridLayout estas ene de la [Ero](https://doc.qt.io/qt-6/ qml-qtquick-item.html) komponanto, kiun ni provizis por la propreco contentItem. Ĉi tiu estas la Ero kiu enhavas tion, kio estos montrata en via karto.

Ni ankaŭ devas elekti aranĝon por niaj komponantoj, por ke ili ne nur amasiĝu unu sur la alian. Estas tri ĉefaj tipoj, kiujn ni povas elekti:

  • ColumnLayout aranĝas viajn komponantojn vertikale, en ununura kolumno
  • RowLayout aranĝas viajn komponantojn horizontale, en ununura vico
  • GridLayout prezentas viajn komponantojn en krado kun komponado de via elekto

Kun ColumnLayout kaj [RowLayout](https://doc.qt.io/qt-6/qml- qtquick-layouts-rowlayout.html), ĉio, kion ni devas fari, estas skribi niajn komponantojn ene de la Layout-komponento. Kiel vi povas vidi, ni iris kun GridLayout, kiu implicas iom pli da manlaboro.

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

La unua afero, kiun vi vidas, estas niaj ankroj. La ankra sistemo de QtQuick provizas utilan manieron certigi, ke viaj komponantoj estas poziciigitaj en certaj partoj de gepatra komponanto. Ni ankris nian GridLayout maldekstren, supre kaj dekstren de la gepatra karto, certigante ke nia enhavo etendiĝas transe. la tuta karto.

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:

Kirigami UnuoRastrumeroj
malgranda interspaco4px
granda interspaco8px
gridUnit18px

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.

Internaj komponantoj

We could just create three labels within our delegate component and call it a day, but that wouldn't look particularly nice. We'll make use of a few more convenient components:

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")
    }
}
How the custom Card looks like

How the custom Card looks like

  • Maldekstre, Kirigami.Titolo : uzas la daton' de ListElement` kiel 1-nivelan titolon.
  • Meze, ColumnLayout: havas Kirigami.Heading kiu montras la taskonomon ; a Kirigami.Separator , kiu provizas la horizontalan linion; kaj Controls.Label , kiu montras la laŭvolan priskribon de tasko. La lastaj du komponantoj havas videblan proprecon, kiu kontrolas ĉu la priskribo estas malplena aŭ ne kaj montras la komponantoj depende de la rezulto de priskribo.length > 0.
  • Ĝuste, Controls.Button : butono kiu faros ion... baldaŭ!

Nia aplikaĵo ĝis nun

Main.qml:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami

Kirigami.ApplicationWindow {
    id: root

    width: 400
    height: 300

    title: i18nc("@title:window", "Day Kountdown")

    // ListModel needed for ListView, contains elements to be displayed
    ListModel {
        id: kountdownModel
        // Each ListElement is an element on the list, containing information
        ListElement {
            name: "Dog birthday!!"
            description: "Big doggo birthday blowout."
            date: 100
        }
    }

    Component {
        id: kountdownDelegate
        Kirigami.AbstractCard {
            contentItem: Item {
                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 determines the size of the heading
                        level: 1
                        text: date
                    }

                    // Layout for positioning elements vertically
                    ColumnLayout {
                        Kirigami.Heading {
                            Layout.fillWidth: true
                            level: 2
                            text: name
                        }
                        // Horizontal rule
                        Kirigami.Separator {
                            Layout.fillWidth: true
                            visible: description.length > 0
                        }
                        // Labels contain text
                        Controls.Label {
                            Layout.fillWidth: true
                            // Word wrap makes text stay within box and shift with size
                            wrapMode: Text.WordWrap
                            text: description
                            visible: description.length > 0
                        }
                    }
                    Controls.Button {
                        Layout.alignment: Qt.AlignRight
                        // Column spanning within grid layout (vertically in this case)
                        Layout.columnSpan: 2
                        text: i18n("Edit")
                        //onClicked: to be done...
                    }
                }
            }
        }
    }

    pageStack.initialPage: Kirigami.ScrollablePage {
        title: i18nc("@title", "Kountdown")

        // List view for card elements
        Kirigami.CardsListView {
            id: cardsView
            // Model contains info to be displayed
            model: kountdownModel
            // Delegate is how the information will be presented in the ListView
            delegate: kountdownDelegate
        }
    }
}

Ekrankopio de la aplikaĵo post kompletigado de ĉi tiu leciono

Do estas nia baza karto!

Kun ĉi tiuj paŝoj, ni nun metis la bazan bazon por aldoni ĉiujn funkciojn al nia programo.