Postavitve, seznam pogledov in kartice

Ugotavljanje različnih načinov postavitve stvari na stran

Postavitev vsebine

Zdaj, ko razumemo, kako delujejo strani, je čas, da dodamo stvari našim. Preiskali bomo številne pomembne komponente in elemente postavitve, ki bodo uporabni pri načrtovanju naše aplikacije.

Ne bodite prestrašeni z velikimi kosi kode! Preiskali bomo vse, kar še nismo še spoznali in do konca tega razdelka pa boste imeli aplikacijo, ki je lepo deluje.

Seznam pogledov

Če ste kdaj uporabljali Discover, NeoChat ali Plasmine sistemske nastavitve, ste naleteli na seznam pogledov. Preprosto, seznam pogledov vam dovoli prikaz podatkov v seznamu.

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

To se zdi skrivnostno, ampak ne skrbite. Začnimo pri vrhu.

Prva stvar, ki jo boste opazili, je, da uporabljamo 'Kirigami.CardsListView'. To je seznam pogledov, ki nam omogoča enostavno prikazovanje kartic na seznamu. Vendar je seznam pogledov narejen tako, da prikazuje podatke, ki jih vzamemo iz modela - da se samodejno napolnijo iz nabora podatkov, na katere jih usmerimo. Tam vpliva lastnost 'model': v tem primeru kaže na 'kountdownModel'.

Model

ListModel {
    id: kountdownModel
    // Vsak element seznama je element na seznamu, ki vsebuje informacije
    ListElement { name: "Dog birthday!!"; description: "Big doggo birthday blowout."; date: 100 }
}

Model določa način strukture vnosa podatkov. S pogledom na naš element seznama ListElement zgoraj lahko vidimo, kako so elementi modela kountdownModel strukturirani: vsebujejo ime, opis in datum. Prva dva sta samo niza, tretja pa število, ki jo uporabljamo kot določbo lokacije.

Modeli so uporabni tudi v tem, kako jih je mogoče spremeniti z uporabo več metod. Nekatere pomembne so:

  • ListModelName.append(jsobject yourobject) doda predmet v JavaScript, ki ga posredujete v ListModel, in ga postavi za zadnjim elementom v modelu. Če želite, da se to pravilno zgodi, morate predmetu JavaScript zagotoviti pravilne lastnosti in ustrezne vrste podatkov.
  • ListModelName.get(int index) vrne JSObject na mestu indeksa, ki ga navedete.
  • ListModelName.remove(int index, int count) odstrani JSObject na predvidenem mestu indeksa in tolikokrat po tem mestu indeksa, kot želite (1 vključuje samo JSObject na danem indeksu)
  • ListModelName.set(int index, jsobject yourobject) spremeni postavko na zagotovljenem mestu indeksa z vrednostmi, navedenimi v vašemu predmetu. Enaka pravila so kot pri '.append'.

Delegat

Delegat obravnava, kako bodo prikazani podatki seznama modelov v seznamu pogledov. Elementi CardsListView so zasnovani z delegati tipa kartice v mislih, in dejansko smo uporabili element 'Kirigami.AbstractCard' kot naš delegat v izvlečku zgoraj.

Delegati samodejno prejmejo lastnosti seznama elementov, ki smo jih določili v našem modelu. Zato lahko samo napotimo na lastnosti name, description, in date našega seznama elementov, kot da so konvencionalne spremenljivke znotraj našega delegata.

Gradnja naše kartice delegata

Component {
    id: kountdownDelegate
    Kirigami.AbstractCard {
        contentItem: Item {
            // implicitWidth/Height določi naravno širino/višino elementa, če ni določena širina ali
            // višina. Spodnja nastavitev določa želeno velikost komponente na podlagi njene vsebine
            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")
                    // onClicked: za opraviti... kmalu!
                }
            }
        }
    }
}

implicitWidth in implicitHeight

Kirigami.AbstractCard {
    contentItem: Item {
        implicitWidth: delegateLayout.implicitWidth
        implicitHeight: delegateLayout.implicitHeight
        GridLayout {
            id: delegateLayout
            ...
        }
    }
}

Če pogledamo našo Kirigami.AbstractCard, so prve lastnosti, ki smo jih določili, so implicitWidth in implicitHeight. Te smo nastavili na delegateLayout.implicitWidth in delegateLayout.implicitHeight", to je implicitWidth in implicitHeight elementa GridLayout. Implicitne širine in višine so lastnosti, ki so določene kot neke vrste privzete vrednosti, torej če za te komponente ni nastavljena eksplicitna širina ali višina. Zato smo nastavili implicitWidth in implicitHeight naše Kirigami.AbstractCard na GridLayout spodaj, da se zagotovi, da se GridLayout ne razlije iz kartice.

Postavitve

'GridLayout' je znotraj komponente 'Item', ki smo jo zagotovili za lastnost 'contentItem'. To je element, ki vsebuje tisto, kar bo prikazano na vaši kartici.

Izbrati moramo tudi postavitev za naše komponente, tako da se ne bodo kopičili drug na drugega. Obstajajo trije glavni tipi, ki jih lahko izbiramo:

  • ColumnLayout naniza vaše komponente navpično v enem stolpcu
  • RowLayout naniza vaše komponente vodoravno v eni vrstici
  • GridLayout naniza vaše komponente v mreži s sestavo, ki jo izberete

Pri ColumnLayout in RowLayout moramo samo napisati naše komponente znotraj komponente Layout. Kot lahko vidite, smo šli z mrežno postavitev, ki vključuje malo več ročnega dela.

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

Prva stvar, ki jo vidite je naše sidro 'anchor'. Sistem za sidranje QtQuick zagotavlja uporaben način, da zagotovite, da so vaše komponente postavljene na določenih delih nadrejene komponente. Zasidrali smo našo 'GridLayout' levo, vrh in desno od nadrejene kartice, kar zagotavlja, da se naša vsebina razteza čez celotno kartico.

Nato določimo razmik med vrsticami in stolpci znotraj naše mreže, tako da se naše komponente ne kopičijo. Kirigami zagotavlja številne priročne vnaprej določene enote, ki jih je treba uporabiti v ta namen:

Enota KirigamiSlik. točk
smallSpacing4px
largeSpacing8px
gridUnit18 tč

Prav tako smo tukaj uporabili pogoj za spreminjanje števila stolpcev v naši mreži, odvisno od zaslona, ki ga uporabljamo. Če uporabljamo širok zaslon (to je računalniški monitor ali telefon obrnjen leže) bo mreža imela 4 stolpce, sicer bo imela 2.

Notranje komponente

Lahko bi ustvarili tri oznake znotraj naše komponente delegata in končali. Ampak to ne bi bilo videti posebej lepo.

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

  • Levo, Kirigami.Heading: uporablja lastnost ListElement date kot naslov ravni 1.
  • Sredina, ColumnLayout: ima naslov 'Kirigami.Heading', ki prikazuje ime opravila; 'Kirigami.Separator', ki zagotavlja vodoravno črto; in 'Controls.Label', ki prikazuje izbirni opis opravila. Slednji dve komponenti imata lastnost 'visible', ki preverja, ali je opis prazen ali ne in prikazuje komponente glede na rezultat 'description.length > 0'.
  • Desno, 'Controls.Button': gumb, ki bo nekaj naredil... kmalu!

Naša aplikacija doslej

Tu je naša osnovna kartica!

S temi koraki smo zdaj v postavili temeljne podlage za dodajanje vseh funkcionalnosti v našo aplikacijo.