SailfishOS code walkthrough/pl: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 5: Line 5:
[[:SailfishOS_code_walkthrough|English]] | '''Polski'''
[[:SailfishOS_code_walkthrough|English]] | '''Polski'''


''''_<br />Artykuł jest 4 częscią "Kursu wprowadzającego":/wiki/Category:SailfishOS_Polish::Introduction_tutorial_Polish.<br />"< Idź do części 3":/wiki/SailfishOS_using_app_in_emulator_basics_Polish<br />''''_
''''_
Artykuł jest 4 częscią "Kursu wprowadzającego":/wiki/Category:SailfishOS_Polish::Introduction_tutorial_Polish.
"< Idź do części 3":/wiki/SailfishOS_using_app_in_emulator_basics_Polish
''''_


= Omówienie kodu =
= Omówienie kodu =
Line 15: Line 18:
== Wejście aplikacji ==
== Wejście aplikacji ==


'''src/myfirstapp.cpp'''<br />Każda aplikacja dla SailfishOS musi definiować prostą aplikacje Qt C+'''', która utworzy QQuickView oraz stowrzy instancje pliku QML wraz z oknem aplikacji, jako element położony najwyżej w hierarchi. Jednakże aby to osiągnąć nie muszisz robic nic, poza implementacjia pliku QML.
'''src/myfirstapp.cpp'''
Każda aplikacja dla SailfishOS musi definiować prostą aplikacje Qt C+'''', która utworzy QQuickView oraz stowrzy instancje pliku QML wraz z oknem aplikacji, jako element położony najwyżej w hierarchi. Jednakże aby to osiągnąć nie muszisz robic nic, poza implementacjia pliku QML.


Przyjmując, że nazwałeś swój projekt "myfirstapp", szablon aplikacji SailfishOS wygeneruje plik źródłowy src/myfirstapp.cpp, który wykona opisane zadanie za Ciebie. Plik ten jest implementacją punktu wejściowego do Twojej aplikacji, poprzez przekazanie zmiennych argc(ilość argumentów wejściowych) oraz argv(tablica z argumentami wejściwoymi) do funkcji SailfishApp::main(). Funkcja ta tworzy wymagane instancje QGuiApplication praz QQuickView oraz wczytuje Twój plik QML.
Przyjmując, że nazwałeś swój projekt "myfirstapp", szablon aplikacji SailfishOS wygeneruje plik źródłowy src/myfirstapp.cpp, który wykona opisane zadanie za Ciebie. Plik ten jest implementacją punktu wejściowego do Twojej aplikacji, poprzez przekazanie zmiennych argc(ilość argumentów wejściowych) oraz argv(tablica z argumentami wejściwoymi) do funkcji SailfishApp::main(). Funkcja ta tworzy wymagane instancje QGuiApplication praz QQuickView oraz wczytuje Twój plik QML.
Line 23: Line 27:
Szablon aplikacji tworzy plik QML za Ciebie, ale powinieneś być świadomy faktu, że nie da się zmienić nazwy tego pliku bez uaktualnienie deklaracji TARGET w pliku projektu.
Szablon aplikacji tworzy plik QML za Ciebie, ale powinieneś być świadomy faktu, że nie da się zmienić nazwy tego pliku bez uaktualnienie deklaracji TARGET w pliku projektu.


<code>#ifdef QT_QML_DEBUG<br />#include <QtQuick><br />#endif
<code>#ifdef QT_QML_DEBUG
#include <QtQuick>
#endif


#include <sailfishapp.h>
#include <sailfishapp.h>


int main(int argc, char '''argv[])<br />{<br /> // SailfishApp::main() will display "qml/myfirstapp.qml", if you need more<br /> // control over initialization, you can use:<br /> //<br /> // - SailfishApp::application(int, char'''[]) to get the QGuiApplication *<br /> // - SailfishApp::createView() to get a new QQuickView * instance<br /> // - SailfishApp::pathTo(QString) to get a QUrl to a resource file<br /> //<br /> // To display the view, call "show()" (will show fullscreen on device).
int main(int argc, char '''argv[])
{
// SailfishApp::main() will display "qml/myfirstapp.qml", if you need more
// control over initialization, you can use:
//
// - SailfishApp::application(int, char'''[]) to get the QGuiApplication *
// - SailfishApp::createView() to get a new QQuickView * instance
// - SailfishApp::pathTo(QString) to get a QUrl to a resource file
//
// To display the view, call "show()" (will show fullscreen on device).


return SailfishApp::main(argc, argv);<br />}</code>
return SailfishApp::main(argc, argv);
}</code>


== Najwyżej położony Plik QML. ==
== Najwyżej położony Plik QML. ==


'''qml/myfirstapp.qml'''<br />Wszystkie pliki QML, które są wykorzystywane przez aplikację znajdują się w katalogu qml lub w jednym z jego podkatalogów. Kiedy aplikacja jest uruchamiana, funkcja SailfishApp:main() wczyta plik 'qml/myfirstapp.qml':
'''qml/myfirstapp.qml'''
Wszystkie pliki QML, które są wykorzystywane przez aplikację znajdują się w katalogu qml lub w jednym z jego podkatalogów. Kiedy aplikacja jest uruchamiana, funkcja SailfishApp:main() wczyta plik 'qml/myfirstapp.qml':


<code>import QtQuick 2.0<br />import Sailfish.Silica 1.0<br />import "pages"</code>
<code>import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages"</code>


Dwie pierwsze komendy są niezwykle ważne, ponieważ pozwalaja aplikacji zaimportować moduły Qt Quick i Sailfish Silica, które poźniej będa wykorzystywane. Dodaktowo ostatnia komenda powoduje, że możliwe jest bezpośrednie odwoływanie się do plików QML znajdujących się w katalogu "pages".
Dwie pierwsze komendy są niezwykle ważne, ponieważ pozwalaja aplikacji zaimportować moduły Qt Quick i Sailfish Silica, które poźniej będa wykorzystywane. Dodaktowo ostatnia komenda powoduje, że możliwe jest bezpośrednie odwoływanie się do plików QML znajdujących się w katalogu "pages".


<code>ApplicationWindow<br />{<br /> initialPage: Component { FirstPage { } }<br /> cover: Qt.resolvedUrl("cover/CoverPage.qml")<br />}</code>
<code>ApplicationWindow
{
initialPage: Component { FirstPage { } }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
}</code>


Okno aplikacji(ApplicationWindow) jest elementem, który w przypadku Sailfish Silica jest zawsze na najwyższym poziomie w hierarchi aplikacji. Właściwość 'initialPage' określa stronę, która zostanie otwarta jako pierwsza po otwrzeniu aplikacji. Natomiast właściwość 'cover' zawiera ścieżkę do pliku QML, który opisuje jak powinna wyglądać okładka aplikacji, w momencie gdy ta pracuje w tle.
Okno aplikacji(ApplicationWindow) jest elementem, który w przypadku Sailfish Silica jest zawsze na najwyższym poziomie w hierarchi aplikacji. Właściwość 'initialPage' określa stronę, która zostanie otwarta jako pierwsza po otwrzeniu aplikacji. Natomiast właściwość 'cover' zawiera ścieżkę do pliku QML, który opisuje jak powinna wyglądać okładka aplikacji, w momencie gdy ta pracuje w tle.
Line 45: Line 68:
== Pierwsza strona aplikacji ==
== Pierwsza strona aplikacji ==


'''qml/pages/FirstPage.qml'''<br />Poniższy fragemnt kodu tworzy obiekt strony, która będzie kontenerem dla prezentowanych treści.
'''qml/pages/FirstPage.qml'''
Poniższy fragemnt kodu tworzy obiekt strony, która będzie kontenerem dla prezentowanych treści.


<code>Page {<br /> id: page</code>
<code>Page {
id: page</code>


Aby, aktywować ściągane menu, musimy utworzyć element podatny na prztyknięcie(flickable item), który umieści swoje dzieci na powierzchni, które może być przyciągnieta i prztyknięta. Do stworzenia takiego elemenut wykorzystamy komponent SilicaFlickable. Sailfish Silica udostępnia SilicaFlickable, SilicaListView i SilicaGridView, które są rozszerzeniami komponentów z Qt Quick: flickable, list view i grid view.
Aby, aktywować ściągane menu, musimy utworzyć element podatny na prztyknięcie(flickable item), który umieści swoje dzieci na powierzchni, które może być przyciągnieta i prztyknięta. Do stworzenia takiego elemenut wykorzystamy komponent SilicaFlickable. Sailfish Silica udostępnia SilicaFlickable, SilicaListView i SilicaGridView, które są rozszerzeniami komponentów z Qt Quick: flickable, list view i grid view.


<code>SilicaFlickable {<br /> anchors.fill: parent</code>
<code>SilicaFlickable {
anchors.fill: parent</code>


Następnie, dodajmy ściągane menu z jednym elementem opisanym etykietą "Show Page 2". Do elementu przypiszemy akcję dla zdarzenia onClicked, która umieści drugą stronę na szyczycie stosu stron(pageStack)[obsługiwanego przez okno aplikacji]. Uwaga: zarówno PullDownMenu i PushUpMenu musi być zawsze zagnieżdżone wewnatrz jednego z komponentów SilicaFlickable, SilicaListView lub SilicaGridView.
Następnie, dodajmy ściągane menu z jednym elementem opisanym etykietą "Show Page 2". Do elementu przypiszemy akcję dla zdarzenia onClicked, która umieści drugą stronę na szyczycie stosu stron(pageStack)[obsługiwanego przez okno aplikacji]. Uwaga: zarówno PullDownMenu i PushUpMenu musi być zawsze zagnieżdżone wewnatrz jednego z komponentów SilicaFlickable, SilicaListView lub SilicaGridView.


<code> PullDownMenu {<br /> MenuItem {<br /> text: "Show Page 2"<br /> onClicked: pageStack.push(Qt.resolvedUrl("SecondPage.qml"))<br /> }<br /> }</code>
<code> PullDownMenu {
MenuItem {
text: "Show Page 2"
onClicked: pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
}
}</code>


Ustawmy wysokość SilicaFlickable na taką samą jak jej potomkowie.
Ustawmy wysokość SilicaFlickable na taką samą jak jej potomkowie.
Line 63: Line 94:
Na koniec uporządkujmy prezentowaną treść pionow. Element Column ustawia swoich potomków w taki sposób, że są wyrównani względem pinu i nie nakładają się na siebie. Dodatkowo dodamy nagłowek strony wykorzystując element PageHeader. Nagłowek znajduje się zawsze na górze ekranu. Jako treść ustawimy napis powitalny przy pomocy elementu Label.
Na koniec uporządkujmy prezentowaną treść pionow. Element Column ustawia swoich potomków w taki sposób, że są wyrównani względem pinu i nie nakładają się na siebie. Dodatkowo dodamy nagłowek strony wykorzystując element PageHeader. Nagłowek znajduje się zawsze na górze ekranu. Jako treść ustawimy napis powitalny przy pomocy elementu Label.


</code> Column {<br /> id: column
</code> Column {
id: column


width: page.width<br /> spacing: Theme.paddingLarge<br /> PageHeader {<br /> title: "UI Template"<br /> }<br /> Label {<br /> x: Theme.paddingLarge<br /> text: "Hello Sailors"<br /> color: Theme.secondaryHighlightColor<br /> font.pixelSize: Theme.fontSizeExtraLarge<br /> }<br /> }<code>
width: page.width
spacing: Theme.paddingLarge
PageHeader {
title: "UI Template"
}
Label {
x: Theme.paddingLarge
text: "Hello Sailors"
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraLarge
}
}<code>


Właściwości: spacing, label.x, label.color oraz font.pixelSize korzystają z wartości z tematu. Dzięki temu możemy być pewni, że aplikacja dostosowuje się do aktualnei aktywnego tematu i nie rozmija się z komponentami systemowymi.
Właściwości: spacing, label.x, label.color oraz font.pixelSize korzystają z wartości z tematu. Dzięki temu możemy być pewni, że aplikacja dostosowuje się do aktualnei aktywnego tematu i nie rozmija się z komponentami systemowymi.
Line 71: Line 114:
== Strona druga ==
== Strona druga ==


'''qml/pages/SecondPage.qml'''<br />Strona druga jest dosyć prosta. Znajdziemy w niej deklaracje komponent SilicaListView, która posiada właściwość model służącą do definiowania danych które mają być wyświetlone oraz właściwość delegate służącą do definiowania w jaki sposób wyświetlić poszczególny element list.
'''qml/pages/SecondPage.qml'''
Strona druga jest dosyć prosta. Znajdziemy w niej deklaracje komponent SilicaListView, która posiada właściwość model służącą do definiowania danych które mają być wyświetlone oraz właściwość delegate służącą do definiowania w jaki sposób wyświetlić poszczególny element list.


</code>Page {<br /> id: page<br /> SilicaListView {<br /> id: listView<br /> model: 20<br /> anchors.fill: parent<br /> header: PageHeader {<br /> title: "Nested Page"<br /> }<br /> delegate: BackgroundItem {<br /> id: delegate
</code>Page {
id: page
SilicaListView {
id: listView
model: 20
anchors.fill: parent
header: PageHeader {
title: "Nested Page"
}
delegate: BackgroundItem {
id: delegate


Label {<br /> x: Theme.paddingLarge<br /> text: "Item " + index<br /> anchors.verticalCenter: parent.verticalCenter<br /> color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor<br /> }<br /> onClicked: console.log("Clicked " + index)<br /> }<br /> VerticalScrollDecorator {}<br /> }<br />}<code>
Label {
x: Theme.paddingLarge
text: "Item " + index
anchors.verticalCenter: parent.verticalCenter
color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
}
onClicked: console.log("Clicked " + index)
}
VerticalScrollDecorator {}
}
}<code>


== Okładka aplikacji ==
== Okładka aplikacji ==


'''qml/cover/CoverPage.qml'''<br />Okładki to wizualna reprezentacja aplikacji pracujących w tle, okładki wyświetlane są na ekranie pracujących aplikacji. Do utworzenia okładki wykorzystujemy komponent CoverBackground, podając etykietę oraz ją środkując.
'''qml/cover/CoverPage.qml'''
Okładki to wizualna reprezentacja aplikacji pracujących w tle, okładki wyświetlane są na ekranie pracujących aplikacji. Do utworzenia okładki wykorzystujemy komponent CoverBackground, podając etykietę oraz ją środkując.


</code>CoverBackground {<br /> Label {<br /> id: label<br /> anchors.centerIn: parent<br /> text: "My Cover"<br /> }<code>
</code>CoverBackground {
Label {
id: label
anchors.centerIn: parent
text: "My Cover"
}<code>


Okładka może określać liste akcji które mogą być przeprowadzane na aplikacji pracującej w tle. Liste tą definiujemy z użyciem elemntu CoverActionList. Lista ta może zawierać maksymalnie 2 elementy opisujące akcje.
Okładka może określać liste akcji które mogą być przeprowadzane na aplikacji pracującej w tle. Liste tą definiujemy z użyciem elemntu CoverActionList. Lista ta może zawierać maksymalnie 2 elementy opisujące akcje.


</code> CoverActionList {<br /> id: coverAction
</code> CoverActionList {
id: coverAction


CoverAction {<br /> iconSource: "image://theme/icon-cover-next"<br /> }
CoverAction {
iconSource: "image://theme/icon-cover-next"
}


CoverAction {<br /> iconSource: "image://theme/icon-cover-pause"<br /> }<br /> }<code>
CoverAction {
iconSource: "image://theme/icon-cover-pause"
}
}<code>


We wstawce powyżej można zauważyć, że do reprezentacji poszczególnych akcji wykorzystujemy różne ikony. Oczywiście do wymienionych akcji można przypisać funkcje które zareagują na aktywowanie której kolwiek z akcji. Możesz spróbować dodać właściwość onTriggered: console.log("Cover action!") do dowolnej akcji. Przed sprawdzeniem działania zatrzymaj wcześniej uruchomioną aplikację i przebuduj ją, a następnie uruchom ponownie, aby zaobserwować rezultaty.
We wstawce powyżej można zauważyć, że do reprezentacji poszczególnych akcji wykorzystujemy różne ikony. Oczywiście do wymienionych akcji można przypisać funkcje które zareagują na aktywowanie której kolwiek z akcji. Możesz spróbować dodać właściwość onTriggered: console.log("Cover action!") do dowolnej akcji. Przed sprawdzeniem działania zatrzymaj wcześniej uruchomioną aplikację i przebuduj ją, a następnie uruchom ponownie, aby zaobserwować rezultaty.
Line 99: Line 175:
Edytowalne pola tekstowe mogą być dobrym przykładem. TextField jest komponentem Silica, który jest jedno liniowym edytowalnym polem tekstowym. Jednakże istnieje kilka komponentów, które maja bezpośredni wpływ na sposób działania TextField'a.
Edytowalne pola tekstowe mogą być dobrym przykładem. TextField jest komponentem Silica, który jest jedno liniowym edytowalnym polem tekstowym. Jednakże istnieje kilka komponentów, które maja bezpośredni wpływ na sposób działania TextField'a.


Jeśli komponent TextField nie jest zagnieżdżony w komponencie Silica Page, to może zostać zasłonięty przez wirtualną klawiaturę. Komponent Page zapewnia, widoczność edytowalnych pol w przypadku pojawienia się wirtualnej klawiatury na ekranie, poprzez zwijanie treści i możliwość jej przewijania.<br />Podobnym przykładem może być sytuacja, gdy elementem bazowym aplikacji nie jest Silica ApplicationWindow, w tym momencie wirtualna klawiatura nie będzie odpowiednio profilowana, co możę przyczynić sie do trudności z odczytywaniem klawiszy.
Jeśli komponent TextField nie jest zagnieżdżony w komponencie Silica Page, to może zostać zasłonięty przez wirtualną klawiaturę. Komponent Page zapewnia, widoczność edytowalnych pol w przypadku pojawienia się wirtualnej klawiatury na ekranie, poprzez zwijanie treści i możliwość jej przewijania.
Podobnym przykładem może być sytuacja, gdy elementem bazowym aplikacji nie jest Silica ApplicationWindow, w tym momencie wirtualna klawiatura nie będzie odpowiednio profilowana, co możę przyczynić sie do trudności z odczytywaniem klawiszy.


Jeśli napotkasz sytuacje w której Twoja aplikacja zachowuje się inaczej w porównaniu z innymi aplikacjami na Sailfish OS, pierwszym krokiem jaki powinieneś zrobić jest sprawdzenie czy przez przypadek nie użyłeś standardowego komponentu Qt Quick zamiast analogicznego komponentu Silica. Oczywiście ten problem najczęściej występuje w momencie portowanie istniejących już aplikacji napisanych w QML do Sailfish OS.
Jeśli napotkasz sytuacje w której Twoja aplikacja zachowuje się inaczej w porównaniu z innymi aplikacjami na Sailfish OS, pierwszym krokiem jaki powinieneś zrobić jest sprawdzenie czy przez przypadek nie użyłeś standardowego komponentu Qt Quick zamiast analogicznego komponentu Silica. Oczywiście ten problem najczęściej występuje w momencie portowanie istniejących już aplikacji napisanych w QML do Sailfish OS.
Line 119: Line 196:
Tworzenie intuicyjnych aplikacji z wykorzystaniem komponentów Sailfish Silica jest dosyć jasne. Fakt, że komponenty te oparte są o deklaratywny język QML, powoduje że proces jest szybki i prosty. Silica zapewnia bogaty zestaw elementów interfejsu użytkownika i mnóstwo możliwości. Teraz możesz zbadać i dowiedzieć się więcej o tym, jak z nich korzystać w swojej aplikacji. Dobry pomysłem możę być przeanalizowanie przykładu z SDK - Media gallery.
Tworzenie intuicyjnych aplikacji z wykorzystaniem komponentów Sailfish Silica jest dosyć jasne. Fakt, że komponenty te oparte są o deklaratywny język QML, powoduje że proces jest szybki i prosty. Silica zapewnia bogaty zestaw elementów interfejsu użytkownika i mnóstwo możliwości. Teraz możesz zbadać i dowiedzieć się więcej o tym, jak z nich korzystać w swojej aplikacji. Dobry pomysłem możę być przeanalizowanie przykładu z SDK - Media gallery.


''''_<br />Artykuł jest 4 częscią "Kursu wprowadzającego":/wiki/Category:SailfishOS_Polish::Introduction_tutorial_Polish.<br />"< Idź do części 3":/wiki/SailfishOS_using_app_in_emulator_basics_Polish
''''_
Artykuł jest 4 częscią "Kursu wprowadzającego":/wiki/Category:SailfishOS_Polish::Introduction_tutorial_Polish.
"< Idź do części 3":/wiki/SailfishOS_using_app_in_emulator_basics_Polish

Revision as of 11:42, 25 February 2015


[toc align_right="yes" depth="2"]

English | Polski

'_ Artykuł jest 4 częscią "Kursu wprowadzającego":/wiki/Category:SailfishOS_Polish::Introduction_tutorial_Polish. "< Idź do części 3":/wiki/SailfishOS_using_app_in_emulator_basics_Polish '_

Omówienie kodu

Szablon projektu zawiera podstawy prostej aplikacji na Sailfish OS, aby pomóc Ci je zrozumieć omówimy wygenerowany kod.

Podczas tworzenia nowego projekut opartego na szablonie aplikacji SailfishOS, niektóre pliki w projekcie QtCreator są nazwane tak samo jak cały projekt. W dalszej części artykułu przyjmuje się że nazwa projektu to "myfristapp".

Wejście aplikacji

src/myfirstapp.cpp Każda aplikacja dla SailfishOS musi definiować prostą aplikacje Qt C+', która utworzy QQuickView oraz stowrzy instancje pliku QML wraz z oknem aplikacji, jako element położony najwyżej w hierarchi. Jednakże aby to osiągnąć nie muszisz robic nic, poza implementacjia pliku QML.

Przyjmując, że nazwałeś swój projekt "myfirstapp", szablon aplikacji SailfishOS wygeneruje plik źródłowy src/myfirstapp.cpp, który wykona opisane zadanie za Ciebie. Plik ten jest implementacją punktu wejściowego do Twojej aplikacji, poprzez przekazanie zmiennych argc(ilość argumentów wejściowych) oraz argv(tablica z argumentami wejściwoymi) do funkcji SailfishApp::main(). Funkcja ta tworzy wymagane instancje QGuiApplication praz QQuickView oraz wczytuje Twój plik QML.

Zauważ, żę nazwa pliku QML nie jest przekazywana do funkcji SailfishApp:main(). Zamiast tego funkcja oczekuje, że nazwa pliku QML będzie taka jak w właściwości projektu TARGET. Jeśli np nazwą projektu jest "myfirstapp", to domyślnie plik projektu QT (myfirstapp.pro) będzie posiadał następującą deklarację 'TARGET = myfirstapp'. W takim wypadku funkcja main() załaduje następujący plik QML 'qml/myfirstapp.qml'.

Szablon aplikacji tworzy plik QML za Ciebie, ale powinieneś być świadomy faktu, że nie da się zmienić nazwy tego pliku bez uaktualnienie deklaracji TARGET w pliku projektu.

#ifdef QT_QML_DEBUG
#include <QtQuick>
#endif

#include <sailfishapp.h>

int main(int argc, char '''argv[])
{
 // SailfishApp::main() will display "qml/myfirstapp.qml", if you need more
 // control over initialization, you can use:
 //
 // - SailfishApp::application(int, char'''[]) to get the QGuiApplication *
 // - SailfishApp::createView() to get a new QQuickView * instance
 // - SailfishApp::pathTo(QString) to get a QUrl to a resource file
 //
 // To display the view, call "show()" (will show fullscreen on device).

return SailfishApp::main(argc, argv);
}

Najwyżej położony Plik QML.

qml/myfirstapp.qml Wszystkie pliki QML, które są wykorzystywane przez aplikację znajdują się w katalogu qml lub w jednym z jego podkatalogów. Kiedy aplikacja jest uruchamiana, funkcja SailfishApp:main() wczyta plik 'qml/myfirstapp.qml':

import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages"

Dwie pierwsze komendy są niezwykle ważne, ponieważ pozwalaja aplikacji zaimportować moduły Qt Quick i Sailfish Silica, które poźniej będa wykorzystywane. Dodaktowo ostatnia komenda powoduje, że możliwe jest bezpośrednie odwoływanie się do plików QML znajdujących się w katalogu "pages".

ApplicationWindow
{
 initialPage: Component { FirstPage { } }
 cover: Qt.resolvedUrl("cover/CoverPage.qml")
}

Okno aplikacji(ApplicationWindow) jest elementem, który w przypadku Sailfish Silica jest zawsze na najwyższym poziomie w hierarchi aplikacji. Właściwość 'initialPage' określa stronę, która zostanie otwarta jako pierwsza po otwrzeniu aplikacji. Natomiast właściwość 'cover' zawiera ścieżkę do pliku QML, który opisuje jak powinna wyglądać okładka aplikacji, w momencie gdy ta pracuje w tle.

Pierwsza strona aplikacji

qml/pages/FirstPage.qml Poniższy fragemnt kodu tworzy obiekt strony, która będzie kontenerem dla prezentowanych treści.

Page {
 id: page

Aby, aktywować ściągane menu, musimy utworzyć element podatny na prztyknięcie(flickable item), który umieści swoje dzieci na powierzchni, które może być przyciągnieta i prztyknięta. Do stworzenia takiego elemenut wykorzystamy komponent SilicaFlickable. Sailfish Silica udostępnia SilicaFlickable, SilicaListView i SilicaGridView, które są rozszerzeniami komponentów z Qt Quick: flickable, list view i grid view.

SilicaFlickable {
 anchors.fill: parent

Następnie, dodajmy ściągane menu z jednym elementem opisanym etykietą "Show Page 2". Do elementu przypiszemy akcję dla zdarzenia onClicked, która umieści drugą stronę na szyczycie stosu stron(pageStack)[obsługiwanego przez okno aplikacji]. Uwaga: zarówno PullDownMenu i PushUpMenu musi być zawsze zagnieżdżone wewnatrz jednego z komponentów SilicaFlickable, SilicaListView lub SilicaGridView.

 PullDownMenu {
 MenuItem {
 text: "Show Page 2"
 onClicked: pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
 }
 }

Ustawmy wysokość SilicaFlickable na taką samą jak jej potomkowie.

 contentHeight: childrenRect.height <code>

Na koniec uporządkujmy prezentowaną treść pionow. Element Column ustawia swoich potomków w taki sposób, że  wyrównani względem pinu i nie nakładają się na siebie. Dodatkowo dodamy nagłowek strony wykorzystując element PageHeader. Nagłowek znajduje się zawsze na górze ekranu. Jako treść ustawimy napis powitalny przy pomocy elementu Label.

Column {

id: column

width: page.width

spacing: Theme.paddingLarge
PageHeader {
title: "UI Template"
}
Label {
x: Theme.paddingLarge
text: "Hello Sailors"
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraLarge
}

}

Właściwości: spacing, label.x, label.color oraz font.pixelSize korzystają z wartości z tematu. Dzięki temu możemy być pewni, że aplikacja dostosowuje się do aktualnei aktywnego tematu i nie rozmija się z komponentami systemowymi.

== Strona druga ==

'''qml/pages/SecondPage.qml'''
Strona druga jest dosyć prosta. Znajdziemy w niej deklaracje komponent SilicaListView, która posiada właściwość model służącą do definiowania danych które mają być wyświetlone oraz właściwość delegate służącą do definiowania w jaki sposób wyświetlić poszczególny element list.

Page {

id: page
SilicaListView {
id: listView
model: 20
anchors.fill: parent
header: PageHeader {
title: "Nested Page"
}
delegate: BackgroundItem {
id: delegate

Label {

x: Theme.paddingLarge
text: "Item " + index
anchors.verticalCenter: parent.verticalCenter
color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
}
onClicked: console.log("Clicked " + index)
}
VerticalScrollDecorator {}
}

}

== Okładka aplikacji ==

'''qml/cover/CoverPage.qml'''
Okładki to wizualna reprezentacja aplikacji pracujących w tle, okładki wyświetlane  na ekranie pracujących aplikacji. Do utworzenia okładki wykorzystujemy komponent CoverBackground, podając etykietę oraz  środkując.

CoverBackground {

Label {
id: label
anchors.centerIn: parent
text: "My Cover"

}

Okładka może określać liste akcji które mogą być przeprowadzane na aplikacji pracującej w tle. Liste  definiujemy z użyciem elemntu CoverActionList. Lista ta może zawierać maksymalnie 2 elementy opisujące akcje.

CoverActionList {

id: coverAction

CoverAction {

iconSource: "image://theme/icon-cover-next"
}

CoverAction {

iconSource: "image://theme/icon-cover-pause"
}
}

We wstawce powyżej można zauważyć, że do reprezentacji poszczególnych akcji wykorzystujemy różne ikony. Oczywiście do wymienionych akcji można przypisać funkcje które zareagują na aktywowanie której kolwiek z akcji. Możesz spróbować dodać właściwość onTriggered: console.log("Cover action!") do dowolnej akcji. Przed sprawdzeniem działania zatrzymaj wcześniej uruchomioną aplikację i przebuduj ją, a następnie uruchom ponownie, aby zaobserwować rezultaty.

O komponentach Sailfish Silica

Należy podkreślić, że komponenty Sailfish Silica QML zostały zaprojektowane tak by wykorzystywać je razem. Być może nie jest to odrazu oczywiste, jednak aby zapewnić funkcjonalności specyficzne dla platformy, zywkle wykorzystuje się klika komponentów Silica.

Edytowalne pola tekstowe mogą być dobrym przykładem. TextField jest komponentem Silica, który jest jedno liniowym edytowalnym polem tekstowym. Jednakże istnieje kilka komponentów, które maja bezpośredni wpływ na sposób działania TextField'a.

Jeśli komponent TextField nie jest zagnieżdżony w komponencie Silica Page, to może zostać zasłonięty przez wirtualną klawiaturę. Komponent Page zapewnia, widoczność edytowalnych pol w przypadku pojawienia się wirtualnej klawiatury na ekranie, poprzez zwijanie treści i możliwość jej przewijania. Podobnym przykładem może być sytuacja, gdy elementem bazowym aplikacji nie jest Silica ApplicationWindow, w tym momencie wirtualna klawiatura nie będzie odpowiednio profilowana, co możę przyczynić sie do trudności z odczytywaniem klawiszy.

Jeśli napotkasz sytuacje w której Twoja aplikacja zachowuje się inaczej w porównaniu z innymi aplikacjami na Sailfish OS, pierwszym krokiem jaki powinieneś zrobić jest sprawdzenie czy przez przypadek nie użyłeś standardowego komponentu Qt Quick zamiast analogicznego komponentu Silica. Oczywiście ten problem najczęściej występuje w momencie portowanie istniejących już aplikacji napisanych w QML do Sailfish OS.

Inne pliki i foldery w projekcie.

Zwróć uwagę, że oprócz plikow z rozszerzeniami .qml i .cpp istnieje kilka innych plików którch dotąd jeszcze nie omówiliśmy. Zatem omówmy je pokrótce, nim zaczniesz odkrywać SDK na własną ręke.

myfirstapp.desktop jest standardą konfiguracja pulpitu dla Linuxa, która opisuje jak nasz konkretny program powinien być uruchamiany, jak występuje w menusach itd. Plik ten np. określa nazwę oraz ikone aplikacji. Wiecej informacji na temat specyfikacji konfiguracji pulpitu można znaleźć na standards.freedesktop.org

myfirstapp.pn jest ikoną, która jest wykorzystywana przez aplikację. Ikona jest zadeklarowana w pliku konfiguracji pulpitu, do tej konkretnej ikony odnośi się wpis Icon=/usr/share/icons/hicolor/86x86/apps/myfirstapp.png . Szablon aplikacji zajmuje się odpowiednim umiejscowieniem ikony i wpisaniem właściwej deklaracji do pliku .desktop, która zawsze powinna odnośić się do pliku z wykorzystaniem ścieżki absolutnej. Podobnie w jak w przypadku głownego pliku QML, nazwa ikony jest oparta o deklaracje TARGET z pliku projektu. Nazwa ikony nie powinna być zmieniana, dopóki deklaracja TARGET nie zostanie zmieniona.

myfirstapp.pro jest plikiem projektu, który łączy pliki źródłowe i otrzymywaną aplikacje. Plik opisuje jak aplikacja ma być zbudowana poprzez tworzenie pliku Makefile w odpowiednim katalogu, który jest uruchamiany aby skompilować aplikację. Deklaracja CONFIG += sailfishapp powoduje, że Twój projekt zostanie zlinkowany z biblioteką libsailfishapp, która dostarcza implementację funkcji SailfishApp::main(). Deklaracja CONFIG zapewnia również odpowiednie rozlokowanie plików binarnych i danych zarówno w emulatorze jak i w urządzeniu. Aby dowiedzieć się wiecej o pliku projektu zajrzyj do instrkucji qmake.

Katalog qml zawiera pliki, które powinny być zainstalowane jako część Twojej aplikacji. Prócz plikiów QML, audio, obrazów i skryptów, inne pliki które są wykorzystywane przez aplikacje powinny być umieszczone w tym folderze lub w jednym z jego podfolderów. Najprościej mówiąc wszystko co znajduje się w foldedrze qml zostaje zainstalowane w momencie gdy Twoja aplikacja jest instalowana na emulatorze lub urządzeniu.

Podsumowanie

Tworzenie intuicyjnych aplikacji z wykorzystaniem komponentów Sailfish Silica jest dosyć jasne. Fakt, że komponenty te oparte są o deklaratywny język QML, powoduje że proces jest szybki i prosty. Silica zapewnia bogaty zestaw elementów interfejsu użytkownika i mnóstwo możliwości. Teraz możesz zbadać i dowiedzieć się więcej o tym, jak z nich korzystać w swojej aplikacji. Dobry pomysłem możę być przeanalizowanie przykładu z SDK - Media gallery.

'_ Artykuł jest 4 częscią "Kursu wprowadzającego":/wiki/Category:SailfishOS_Polish::Introduction_tutorial_Polish. "< Idź do części 3":/wiki/SailfishOS_using_app_in_emulator_basics_Polish