Be Qt: Vývoj mobilních aplikací v Qt (3) – komponenty

By Řezza - Last updated: Tuesday, April 10, 2012 - Save & Share - Leave a Comment

Doposud jsme se v rámci seriálu o vývoji mobilních aplikací v Qt Quick seznamovali s vývojovým prostředím (Qt SDK a Qt Creatorem) a předvedli jsme si, jak přeložit svou první aplikaci v QML. O tomhle zajímavém deklarativním jazyce jsme si pak podrobněji pověděli v druhé části seriálu. Probrali jsme strukturu QML a aplikací, do krve se nám snad i dostala syntaxe jazyka a máme i představu, kam Qt Quick patří v rámci frameworku Qt. V následujících dílech budeme pokračovat v rozšiřování svých znalostí, v tomto dílu se zaměříme na komponenty v QML.

Komponenty

Komponenty nás budou provázet taky celým článkem – pro začátek to budou komponenty naše vlastní, které výrazně usnadní tvorbu našich aplikací (později se Qt Components bude podrobněji věnovat minimálně jeden celý díl seriálu). Komponenty zpřehlední zdrojový kód, který by se jinak stal dlouhou nudlí skládající se z kopírování a vkládání kusů kódu. Tím se také tyhle části kódu (tedy vlastní komponenty) stanou opakovaně použitelné pro využití jak v rámci aplikace, tak i v dalších následujících projektech. V případě uvolnění pod open source licencí mohou tyto komponenty posloužit i ostatním vývojářům v naší rozrůstající se komunitě. QML jako jazyk je navíc velmi vhodný k rychlému prototypování návrhu aplikace a následný refaktoring aplikace do komponent se udělá v podstatě skoro sám (zhruba vysvětleno: refaktoring je dodatečné vylepšení vnitřní struktury programu). Jazyk QML vývojáře k refaktoringu přímo vybízí a dochází k symbióze návrhu a implementace aplikace.

Vlastní komponenty

Komponenty můžeme nadefinovat jak ve svém novém vlastním souboru, tak i v rámci již existujícího QML zdrojového kódu. První případ je vlastně klasický QML dokument, který obsahuje vyžadované importy (minimálně QtQuick) a jeden prvek nejvyšší úrovně (často se jedná o element Item představený v předchozí části seriálu) s popisem vlastností a chování komponenty. Jméno souboru s definicí komponenty musí začínat velkým písmenem a jméno musí mít příponu .qml. Tímto jménem se pak následně ve zdrojovém kódu aplikace na novou komponentu odkazujeme. Druhou možností je pak vytvoření nové komponenty právě v rámci jiného QML dokumentu (či jiné komponenty). Pro tento případ máme k dispozici element Component. Ten se hojně využívá pro oddělení menší části kódu do samostatné komponenty bez nutnosti vytvářet bokem nový soubor, a to především pro opakující se prvky, např. jako delegát pro opakovače (repeatery) a ListView element, jak jsme si ještě bez znalosti komponent ukázali v minulém dílu. Takto postupujeme především z důvodu přehlednosti zdrojových kódů.

V následujícím příkladu si napíšeme dvě komponenty – čtverec a obdélník a ty následně vytvoříme pomocí elementu Loader do jednoho řádku (element Row), kde se také zobrazí. Všimněte si, že obě komponenty mají vlastní id a to je taky jediná vlastnost, která lze v rámci elementu Component nejvyšší úrovně nastavit. O Loaderu a dalších možnostech, jak vytvářet komponenty dynamicky, si povíme v některém z následujících dílů seriálu o pokročilých vlastnostech QML.

Komponenty čtverec a obdélník vedle sebe

import QtQuick 1.0

Rectangle {
    width: 300
    height: 100

    Component {
        id: ctverec

        Rectangle { width: 100; height: 100; color: "blue" }
    }

    Component {
        id: obdelnik

        Rectangle { width: 200; height: 100; color: "red" }
    }

    Row {
        anchors.fill: parent

        Loader { sourceComponent: ctverec }
        Loader { sourceComponent: obdelnik }
    }
}

Využití v rámci delegátu si představíme v závěru článku v rámci naší první malé, ale skutečné aplikace. Jaká to bude, to si zatím necháme jako tajemství. Nechte se překvapit!

Tlačítko

K tvorbě skutečného uživatelského rozhraní jsou ovšem potřeba přece jenom složitější komponenty, než jen výše předvedený čtverec a obdélník. Mají definované rozličné vlastnosti, složitější chování a případně i reagují na akce uživatele. A čisté Qt Quick nechává tuhle práci na vývojářích. Protože kromě základních elementů představených v minulém dílu seriálu, k obvyklému překvapení vývojářů Qt Quick neobsahuje žádné elementy/komponenty pro tvorbu uživatelských rozhraní. Nyní si ukžeme tvorbu jednoho ze základních prvků rozhraní – tlačítka.

Začneme vytvořením nového souboru (v Qt Creatoru buď pomocí menu File -> New File or Project nebo kliknutím pravého tlačítka ve stromové struktuře projektu a výběrem položky Add New, následně vybereme QML a QML File). Nový soubor pojmenujeme Button.qml. Qt Creator pak předgeneruje šablonu, kterou budeme dále rozvíjet.

import QtQuick 1.1

Rectangle {
    id: container
    width: 100; height: 40; radius: 5

Pro tlačítko použijeme jako výchozí prvek klasický obdélník (Rectangle) a nastavíme jeho id na container. Pomocí vlastnosti radius pak tlačítko trošku zjemníme a zakulatíme jeho rohy.

    property color buttonColor: "red"
    property alias buttonText: label.text

    signal clicked

V další části kódu se dostáváme k první zajímavé a pro tlačítko nejdůležitější části, k definici jeho vlastností a k definici signálu jako reakci na stisk tlačítka. Na prvním řádku je klasická definice vlastnosti – pomocí klíčového slova property, následovaného typem vlastnosti a názvem vlastnosti. Za dvojtečkou se nachází výchozí hodnota vlastnosti – v našem případě tedy bude tlačítko červené. Druhá vlastnost je takzvaný alias na vlastnost jiného prvku. Místo typu se za klíčovým slovem property objevuje další klíčové slovo alias a za dvojtečkou se pak nachází odkaz na zástupnou vlastnost jiného prvku. Čtení a zápis na takto zástupné vlastnosti se automaticky projeví na čtení a zápisu v odkazované vlastnosti daného prvku. V našem případě se projeví na prvku label a jeho vlastnosti text (prvek s id label si nadefinujeme později).

Dále nás zajímá definice signálu – v našem případě je to clicked bez parametrů; pokud jsou parametry potřeba,  je možné je uvést v závorce (každý parametr musí být nějakého typu).

    gradient: Gradient {
        GradientStop { position: 0.0; color: buttonColor }
        GradientStop { position: 1.0; color: Qt.darker(buttonColor, 2.0) }
    }

Pro pozadí tlačítka (tedy pro výplň prvku container) použijeme barevný přechod z barvy určené naší vlastností buttonColor na její tmavší variantu – za použití vestavěné funkce darker objektu Qt. Pokud by nám stačila jednobarevná výplň, mohli bychom opět na barvu pozadí použít alias vlastnosti.

    Text {
        id: label
        anchors.centerIn: parent; color: "white"
    }

A dostáváme se k textu tlačítka, na který jsme si výše připravili alias buttonText. Pro naše účely tedy stačí nastavit id komponenty Text na stejnou hodnotu jako v aliasu (to znamená na hodnotu label). Všimněte si, že vůbec nenastavujeme hodnotu vlastnosti text komponenty Text. Ta se nastaví právě přes alias. Pouze vycentrujeme text na střed tlačítka a nastavíme jeho barvu na bílou.

    MouseArea {
        anchors.fill: parent

        onClicked: container.clicked()
    }
}

Udělali jsme poslední krok – naučili jsme naše tlačítko naslouchat příkazům uživatele. Opět použijeme již představený element MouseArea, který roztáhneme na celé naše tlačítko (vlastnost anchors.fill), a nadefinujeme reakci na jeho signál onClicked. Tedy signál, který reaguje na stisk tlačítka myši (či dotek na dotykovém zařízení), a jako akci vyšleme náš vlastní signál clicked bez parametrů.

Tím jsme vytvořili svou první komponentu – tlačítko.

Nezbývá, než se potěšit výsledkem a tlačítko použít v aplikaci. Tato ukázková aplikace vytvoří dvě tlačítka. Kontejner Row (je to standardní prvek jazyka QML) zajistí, že tlačítka budou umístěna vodorovně vedle sebe. První tlačítko bude ve výchozí podobě červené (viz výchozí vlastnost) a druhému nastavíme vlastnost buttonColor na zelenou barvu a bude tedy zelené. Při kliknutí se do konzole vypíše buď „Ahoj“ nebo „Hi“ v závislosti na stisknutém tlačítku.

Naše první tlačítka - Ahoj a Hi

import QtQuick 1.1

Row {
    width: 210; height: 40; spacing: 5

    Button { buttonText: "Ahoj"; onClicked: console.log("Ahoj") }
    Button { buttonText: "Hi"; buttonColor: "Green"; onClicked: console.log("Hi") }
}

Závěr

V příštím dílu seriálu se podíváme na funkce, které dělají moderní uživatelské rozhraní moderním (a to někdy k nelibosti některých uživatelů) – na animace. Ty nás pak přivedou ke stavům a přechodům.

Sdílejte:

Share this:

Posted in MeeGo, Openmobility, Vývoj • • Top Of Page

Write a comment


Yandex Mail.ru Google LiveJournal myOpenId Flickr claimId Blogger Wordpress OpenID Yahoo Technorati Vidoop Verisign AOL