[Go mobile!] Tworzymy pierwszą aplikację cz. 1

Wszystkie artykuły z serii Go mobile! znajdziesz tutaj.

Jeśli na bieżąco śledzisz artykuły z serii Go mobile!, masz już wystarczającą wiedzę teoretyczną, aby napisać pierwszy program.

W tym oraz kolejnym artykule przedstawię instrukcję, dzięki której napiszesz swoją pierwszą aplikację w Ubuntu SDK. I nie będzie do klasyczny Hello world!, a narzędzie do konwersji grid unit na piksele i odwrotnie. W pierwszej części zajmiemy się stworzeniem interfejsu graficznego, w drugiej – logiką aplikacji.

Do dzieła!

Otwórz narzędzie Qt Creator i utwórz w nim nowy plik QML – nazwij go konwerter. Pierwszym krokiem będzie zaprojektowanie interfejsu graficznego. Pozwól, że zrobię to za Ciebie – wyobraź sobie, że poniższy obraz powstał na kartce papieru i jest jedynie szkicem interfejsu.

Do tego będziemy dążyć

Do tego będziemy dążyć

W przedstawionym projekcie można wyróżnić kilka charakterystycznych elementów – oczywiście możesz ten sam interfejs zaprojektować inaczej! Ponieważ zdecydowałem się na layout tabelaryczny (kolumny i wiersze), na czerwono zaznaczono kolumny, a na zielono wiersze.

Zaproponowany przeze mnie podział elementów

Zaproponowany przeze mnie podział elementów

Poniższy kod odpowiada za zaprezentowaną wyżej strukturę aplikacji:

import QtQuick 2.0
import Ubuntu.Components 0.1

MainView {
    id: root
    width: units.gu(42)
    height: units.gu(30)

    Column {
        id: columnA
        spacing: units.gu(1)

        anchors {
            fill: parent
            margins: units.gu(2)
        }

        Row {
            id: rowA1
            spacing: units.gu(2)
            width: parent.width

        }

        Row {
            id: rowA2
            spacing: units.gu(2)
            width: parent.width

        }

        Row {
            id: rowA3
            spacing: units.gu(2)
            width: parent.width

            Column {
                id: columnA31

            }
            Column {
                id: columnA32
                width: parent.width * 0.4

            }
        }
    }
}

Główna kolumna została oznaczona identyfikatorem columnA, a należące do niej wiersze kolejno: rowA1, rowA2, rowA3. Ostatni wiersz składa się z dwóch kolumn: columnA31 oraz columnA32.

Rozmiary głównego kontenera MainView o identyfikatorze root zostały ustalone z wykorzystaniem jednostki gu (grid unit) za pomocą właściwości width (szerokość) oraz height (wysokość).

    id: root
    width: units.gu(42)
    height: units.gu(30)

W kontenerze znajduje się element Column o identyfikatorze columnA. Za pomocą właściwości spacing ustaw odstępy między elementami potomnymi, czyli tymi, które będą tworzone wewnątrz columnA. Rozmiar columnA został dopasowany do rodzica (fill: parrent), a margines, czyli odległość elementu od rodzica (w tym przypadku root) ustal na 2 gu (właściwość margins).

        id: columnA
        spacing: units.gu(1)

        anchors {
            fill: parent
            margins: units.gu(2)
        }

W skład columnA wchodzą trzy wiersze – wszystkie o szerokości równej szerokości rodzica (parrent.width), którym jest columnA.

        Row {
            id: rowA1
            spacing: units.gu(2)
            width: parent.width
 
        }

Dodatkowo trzeci wiersz został podzielony na dwie kolumny – columnA31 oraz columnA32. Szerokość columnA31 została ustalona na 60% szerokości rodzica (width: parent.width * 0.6), a columnA32 na 40%.

        Row {
            id: rowA3
            spacing: units.gu(2)
            width: parent.width

            Column {
                id: columnA31
                width: parent.width * 0.6

            }
            Column {
                id: columnA32
                width: parent.width * 0.4

            }
        }

To tyle jeśli chodzi o szkielet interfejsu – pora dodać do niego odpowiednie elementy.

rowA1

Wiersz ten zawiera dwa przełączniki (Switch) oraz dwie etykiety (Label) – wszystkie elementy ułożone są „obok siebie”.

Stwórz pierwszy przełącznik o identyfikatorze guToPx:

            Switch {
                id: guToPx
                checked: true;

            }

Przełącznik jest elementem o dwóch stanach – checked: true oraz checked: false. Po starcie aplikacji, przełącznik guToPx będzie przełączany w stan true (checked: true).
Obok przełącznika guToPx umieść etykietę wyjaśniającą jego przeznaczenie (text: "gu → px"):

            Label {
                text: "gu → px"

                anchors {
                    verticalCenter: guToPx.verticalCenter
                }
            }

Dodatkowo etykieta zostanie pionowo wyśrodkowana względem przełącznika, którego dotyczy (verticalCenter: guToPx.verticalCenter)
Analogicznie utwórz drugi przełącznik i etykietę:

            Switch {
                id: pxToGu

            }
            Label {
                text: "px → gu"

                anchors {
                    verticalCenter: pxToGu.verticalCenter
                }
            }

rowA2

Drugi wiersz składa się z etykiety (Label) oraz pola tekstowego (TextField).

            Label {
                id: label
                text: "Wartość: "

                anchors {
                    verticalCenter: value.verticalCenter
                }
            }

            TextField {
                id: value

            }

columnA31

columnA31 zawiera jedynie jedną etykietę, która dzięki zastosowaniu znaczników nowej linii (\n) rozchodzi się aż na 4 „wirtualne” wiersze.

                Label {
                    text: "Większość laptopów\n\nLaptop z ekranem Retina\n\nSmartfon 4\" HD\n\nTablet 10\" HD"
                }

columnA32

columnA32, podobnie jak sąsiad, zawiera tylko jedną etykietę. Ponieważ jej tekst będzie zmieniany w zależności od wyniku obliczeń, należy nadać jej identyfikator wynik:

                Label {
                    id: results
                    text: "0 px\n\n0 px\n\n0 px\n\n0 px"
                }

Podsumowanie

Kod odpowiedzialny za interfejs użytkownika:

import QtQuick 2.0
import Ubuntu.Components 0.1

MainView {
    id: root
    width: units.gu(42)
    height: units.gu(30)

    Column {
        id: columnA
        spacing: units.gu(1)

        anchors {
            fill: parent
            margins: units.gu(2)
        }

        Row {
            id: rowA1
            spacing: units.gu(2)
            width: parent.width

            Switch {
                id: guToPx
                checked: true;

            }
            Label {
                text: "gu → px"

                anchors {
                    verticalCenter: guToPx.verticalCenter
                }
            }
            Switch {
                id: pxToGu

            }
            Label {
                text: "px → gu"

                anchors {
                    verticalCenter: pxToGu.verticalCenter
                }
            }
        }

        Row {
            id: rowA2
            spacing: units.gu(2)
            width: parent.width

            Label {
                id: label
                text: "Wartość: "

                anchors {
                    verticalCenter: value.verticalCenter
                }
            }

            TextField {
                id: value

            }
        }

        Row {
            id: rowA3
            spacing: units.gu(2)
            width: parent.width

            Column {
                id: columnA31
                width: parent.width * 0.6

                Label {
                    text: "Większość laptopów\n\nLaptop z ekranem Retina\n\nSmartfon 4\" HD\n\nTablet 10\" HD"
                }
            }
            Column {
                id: columnA32
                width: parent.width * 0.4

                Label {
                    id: results
                    text: "0 px\n\n0 px\n\n0 px\n\n0 px"
                }
            }
        }
    }
}
Jeżeli powyższy artykuł nie rozwiązał lub rozwiązał częściowo Twój problem, dodaj swój komentarz opisujący, w którym miejscu napotkałeś trudności.
Mile widziane komentarze z uwagami lub informacjami o rozwiązaniu problemu.
  • Michal

    Samo tworzenie interfejsu jest dziecinnie proste, niczym tworzenie tabelek w html. Programowanie w js jest jednak masakrą, Ubuntu nie dostarcza (?) dokumentacji, a js nie jest samo wystarczającym językiem.