Difference between revisions of "Qt Quick Carousel/bg"

From Qt Wiki
Jump to: navigation, search
 
Line 1: Line 1:
'''Български''' [[Qt Quick Carousel|English]]
+
[[Category:Developing_with_Qt::Qt Quick]]
  
=Как да направим въртележка с Qt Quick=
+
'''Български''' [[:Qt_Quick_Carousel|English]]
  
==Въведение==
+
[toc align_right="yes" depth="2"]
  
Този урок ще ви покаже как да създадете анимирано меню с елементи, въртящи се в псевдо 3D пространство. Също ще ви бъде показано как да разделите <span class="caps">QML</span> проекта на отделни модули и как да добавите поддръжка на различни езици с ''Qt Linguist''.
+
= Как да направим въртележка с Qt Quick =
  
Всичко, от което се нуждаете, за да изпълните инструкциите е '''qmlviewer'''. Ако използвате някоя от последните версии на Убунту, просто инсталирайте пакетите '''qt4-qmlviewer''' и '''libqt4-dev'''. Всички файлове от урока могат да бъдат намерени в [https://www.gitorious.org/qt-training/qml-demos/trees/master/carousel gitorious] ''[gitorious.org]'' .
+
== Въведение ==
 +
 
 +
Този урок ще ви покаже как да създадете анимирано меню с елементи, въртящи се в псевдо 3D пространство. Също ще ви бъде показано как да разделите QML проекта на отделни модули и как да добавите поддръжка на различни езици с ''Qt Linguist''.
 +
 
 +
Всичко, от което се нуждаете, за да изпълните инструкциите е '''qmlviewer'''. Ако използвате някоя от последните версии на Убунту, просто инсталирайте пакетите '''qt4-qmlviewer''' и '''libqt4-dev'''. Всички файлове от урока могат да бъдат намерени в &quot;gitorious&amp;quot;:https://www.gitorious.org/qt-training/qml-demos/trees/master/carousel .
  
 
Qt Quick трябва да бъде поне версия 1.0, която идва с Qt 4.7.1 и нагоре.
 
Qt Quick трябва да бъде поне версия 1.0, която идва с Qt 4.7.1 и нагоре.
  
==Запознаване с PathView==
+
== Запознаване с PathView ==
  
[http://developer.qt.nokia.com/doc/qt-4.7/qml-pathview.html PathView] ''[developer.qt.nokia.com]'' взима елементи от модел и ги разполага по определен път. Пътят е геометрично дефиниран като последователност от участъци. Има три вида участъци: линии, квадратични и кубични криви на [http://en.wikipedia.org/wiki/Bezier_curve Безие] ''[en.wikipedia.org]'' curves. За да придобиете опит в това, как да създавате пътища, нека започнем с най-обикновен участък под формата на права линия:
+
&quot;PathView&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-pathview.html взима елементи от модел и ги разполага по определен път. Пътят е геометрично дефиниран като последователност от участъци. Има три вида участъци: линии, квадратични и кубични криви на &quot;Безие&amp;quot;:http://en.wikipedia.org/wiki/Bezier_curve curves. За да придобиете опит в това, как да създавате пътища, нека започнем с най-обикновен участък под формата на права линия:
  
''PathView'' е нашият главен елемент. Слагайки числото 32 като модел, автоматично ще се генерират индекси за модела от 0 до 31. За всеки елемент от модела се създава по един делегат, за да се визуализира. Започваме с обикновено текстово поле, което показва индексите на елементите в модела. По-късно ще видим как се създават по-сложни делегати, но за сега нека да се фокусираме върху създаването на пътищата. Описанието на път изисква поне начална точка и един участък. В нашият случай започваме от (0, 0) и рисуваме праволинеен участък до долу в дясно. Като заредите файла в '''qmlviewer''', трябва да получите подобен изход:<br />[[Image:Carousel0.png|Carousel0.png]]
+
<code><br />// Carousel0.qml<br />import QtQuick 1.0
 +
 
 +
PathView {<br /> id: view<br /> width: 640<br /> height: 360<br /> model: 32<br /> delegate: Text { text: index }<br /> path: Path {<br /> startX: 0<br /> startY: 0<br /> PathLine { x: view.width; y: view.height }<br /> }<br />}<br /></code>
 +
 
 +
''PathView'' е нашият главен елемент. Слагайки числото 32 като модел, автоматично ще се генерират индекси за модела от 0 до 31. За всеки елемент от модела се създава по един делегат, за да се визуализира. Започваме с обикновено текстово поле, което показва индексите на елементите в модела. По-късно ще видим как се създават по-сложни делегати, но за сега нека да се фокусираме върху създаването на пътищата. Описанието на път изисква поне начална точка и един участък. В нашият случай започваме от (0, 0) и рисуваме праволинеен участък до долу в дясно. Като заредите файла в '''qmlviewer''', трябва да получите подобен изход:<br />[[Image:http://www.gitorious.org/qt-training/qml-demos/blobs/raw/4ef3dccc2be296484845628880c5abcebbbceb1e/carousel/Carousel0.png|Carousel0.png]]
  
 
Когато плъзгате елементите, те реалистично ще се преместват. Забележете как те застават на фиксирани места. По подразбиране първият елемент е центриран в началната точка, а останалите са разпределени равномерно по дължината на пътя.
 
Когато плъзгате елементите, те реалистично ще се преместват. Забележете как те застават на фиксирани места. По подразбиране първият елемент е центриран в началната точка, а останалите са разпределени равномерно по дължината на пътя.
Line 21: Line 29:
 
Добре, нека да усложним малко примера и да нарисуваме цял правоъгълник. Заменете описанието на пътя от предният пример със следното:
 
Добре, нека да усложним малко примера и да нарисуваме цял правоъгълник. Заменете описанието на пътя от предният пример със следното:
  
Когато стартирате програмата, трябва да видите правоъгълник. Всеки [http://developer.qt.nokia.com/doc/qt-4.7/qml-pathline.html PathLine] ''[developer.qt.nokia.com]'' започва от крайната точна на предният участък, така че ние трябва да зададем само крайните точни на всеки участък. За последният участък просто задаваме началната точка и така затваряме пътя. Създаваме наше си свойство ''pathMargin'', за да си помогнем да дефинираме геометрията на пътя. Използването на потребителски свойства е най-лесният начин за създаване на допълнителни променливи в Qt Quick, но трябва да внимавате, защото те винаги са с публичен достъп.
+
<code><br />// Carousel1.qml<br />…<br />property int pathMargin: 50<br />path: Path {<br /> startX: pathMargin<br /> startY: pathMargin<br /> PathLine { x: view.width - pathMargin; y: pathMargin }<br /> PathLine { x: view.width - pathMargin; y: view.height - pathMargin }<br /> PathLine { x: pathMargin; y: view.height - pathMargin }<br /> PathLine { x: path.startX; y: path.startY }<br />}<br />…<br /></code>
 +
 
 +
Когато стартирате програмата, трябва да видите правоъгълник. Всеки &quot;PathLine&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-pathline.html започва от крайната точна на предният участък, така че ние трябва да зададем само крайните точни на всеки участък. За последният участък просто задаваме началната точка и така затваряме пътя. Създаваме наше си свойство ''pathMargin'', за да си помогнем да дефинираме геометрията на пътя. Използването на потребителски свойства е най-лесният начин за създаване на допълнителни променливи в Qt Quick, но трябва да внимавате, защото те винаги са с публичен достъп.
  
 
Може да искате да напишете:
 
Може да искате да напишете:
 +
 +
<code><br />…<br />path: Path {<br /> property int pathMargin: 50<br /> startX: pathMargin<br />…<br /></code>
  
 
… но това не е възможно, защото ''Path'' компонента вече е дефиниран някъде другаде и не ние е позволено да добавяме нови свойства по време на изпълнение.
 
… но това не е възможно, защото ''Path'' компонента вече е дефиниран някъде другаде и не ние е позволено да добавяме нови свойства по време на изпълнение.
  
==Създаване на кръг==
+
== Създаване на кръг ==
  
След като се научихме да създаваме правоъгълник, нека да опитаме нещо по-трудно кръг. ''Path'' не поддържа кръгли криви, така че ще трябва да използваме приближение чрез някои от следните варианти: линии, квадратични или кубични криви ви Безие. Тъй като това не е урок по аналитична геометрия, нека директно да преминем на решението 4 кубични криви, като използваме [http://www.tinaja.com/glib/ellipse4.pdf магическото число 0.551784] ''[tinaja.com]''. Погледнете кода:
+
След като се научихме да създаваме правоъгълник, нека да опитаме нещо по-трудно - кръг. ''Path'' не поддържа кръгли криви, така че ще трябва да използваме приближение чрез някои от следните варианти: линии, квадратични или кубични криви ви Безие. Тъй като това не е урок по аналитична геометрия, нека директно да преминем на решението - 4 кубични криви, като използваме &quot;магическото число 0.551784&amp;quot;:http://www.tinaja.com/glib/ellipse4.pdf. Погледнете кода:
  
Това ни дава перфектен кръг:<br />[[Image:Carousel2.png|Carousel2.png]]
+
<code><br />// Carousel2.qml<br />…<br />property int pathMargin: 50<br />property real rx: ry // view.width / 2 - pathMargin<br />property real ry: view.height / 2 - pathMargin<br />property real magic: 0.551784<br />property real mx: rx * magic<br />property real my: ry * magic<br />property real cx: view.width / 2<br />property real cy: view.height / 2<br />path: Path {<br /> startX: view.cx + view.rx; startY: view.cy<br /> PathCubic { // first quadrant arc<br /> control1X: view.cx + view.rx; control1Y: view.cy + view.my<br /> control2X: view.cx + view.mx; control2Y: view.cy + view.ry<br /> x: view.cx; y: view.cy + view.ry<br /> }<br /> PathCubic { // second quadrant arc<br /> control1X: view.cx - view.mx; control1Y: view.cy + view.ry<br /> control2X: view.cx - view.rx; control2Y: view.cy + view.my<br /> x: view.cx - view.rx; y: view.cy<br /> }<br /> PathCubic { // third quadrant arc<br /> control1X: view.cx - view.rx; control1Y: view.cy - view.my<br /> control2X: view.cx - view.mx; control2Y: view.cy - view.ry<br /> x: view.cx; y: view.cy - view.ry<br /> }<br /> PathCubic { // forth quadrant arc<br /> control1X: view.cx + view.mx; control1Y: view.cy - view.ry<br /> control2X: view.cx + view.rx; control2Y: view.cy - view.my<br /> x: view.cx + view.rx; y: view.cy<br /> }<br />}<br />…<br /></code>
 +
 
 +
Това ни дава перфектен кръг:<br />[[Image:http://www.gitorious.org/qt-training/qml-demos/blobs/raw/4ef3dccc2be296484845628880c5abcebbbceb1e/carousel/Carousel2.png|Carousel2.png]]
  
 
Както може да видите, ние се нуждаем от по две контролни точки за всяка кубична крива. (Всички точки се дават в абсолютни координати.) Ако бяхме използвали квадратична крива, щяхме да се нуждаем само от една контролна точка. Контролните точки лежат извън кривата, но влияят на нейната форма. Може би сте запознати с концепцията от инструментите за работа с векторна графика.
 
Както може да видите, ние се нуждаем от по две контролни точки за всяка кубична крива. (Всички точки се дават в абсолютни координати.) Ако бяхме използвали квадратична крива, щяхме да се нуждаем само от една контролна точка. Контролните точки лежат извън кривата, но влияят на нейната форма. Може би сте запознати с концепцията от инструментите за работа с векторна графика.
  
==Скриване на логиката==
+
== Скриване на логиката ==
  
<span class="caps">QML</span> файла [http://doc.qt.nokia.com/4.7/qml-extending-types.html#defining-new-components може да се дефинира като преизползваем компонент] ''[doc.qt.nokia.com]''. Когато кода ви расте, вие обикновено искате да го разделите на логически блокове в отделни файлове, за да може да се използва многократно и да е по-лесен за четене. В нашият пример ще го разделим на:
+
QML файла &quot;може да се дефинира като преизползваем компонент&amp;quot;:http://doc.qt.nokia.com/4.7/qml-extending-types.html#defining-new-components. Когато кода ви расте, вие обикновено искате да го разделите на логически блокове в отделни файлове, за да може да се използва многократно и да е по-лесен за четене. В нашият пример ще го разделим на:
 +
 
 +
<code><br />// Carousel3.qml<br />import QtQuick 1.0
 +
 
 +
PathView {<br /> id: view<br /> width: 640<br /> height: 360<br /> model: 32<br /> delegate: Text { text: index }<br /> path: Ellipse {<br /> width: view.width<br /> height: view.height<br /> }<br />}<br /></code>
  
 
Нашият ''Ellipse'' компонент скрива сложната логика за апроксимиране на кръга и скалиране на елементите. Когато дефинираме наши компоненти, поризлизащи от вече съществуващи, можем да дефинираме и нови свойства. Компонента ''Ellipse'' съдържа следният код, който е леко променена версия на предният:
 
Нашият ''Ellipse'' компонент скрива сложната логика за апроксимиране на кръга и скалиране на елементите. Когато дефинираме наши компоненти, поризлизащи от вече съществуващи, можем да дефинираме и нови свойства. Компонента ''Ellipse'' съдържа следният код, който е леко променена версия на предният:
 +
 +
<code><br />// Ellipse.qml<br />import QtQuick 1.0
 +
 +
Path {<br /> id: p<br /> property real width: 200<br /> property real height: 200<br /> property real margin: 50<br /> property real cx: width / 2<br /> property real cy: height / 2<br /> property real rx: width / 2 - margin<br /> property real ry: height / 2 - margin<br /> property real mx: rx * magic<br /> property real my: ry * magic<br /> property real magic: 0.551784<br /> startX: p.cx; startY: p.cy + p.ry<br /> PathCubic { // second quadrant arc<br /> control1X: p.cx - p.mx; control1Y: p.cy + p.ry<br /> control2X: p.cx - p.rx; control2Y: p.cy + p.my<br /> x: p.cx - p.rx; y: p.cy<br /> }<br /> PathCubic { // third quadrant arc<br /> control1X: p.cx - p.rx; control1Y: p.cy - p.my<br /> control2X: p.cx - p.mx; control2Y: p.cy - p.ry<br /> x: p.cx; y: p.cy - p.ry<br /> }<br /> PathCubic { // forth quadrant arc<br /> control1X: p.cx + p.mx; control1Y: p.cy - p.ry<br /> control2X: p.cx + p.rx; control2Y: p.cy - p.my<br /> x: p.cx + p.rx; y: p.cy<br /> }<br /> PathCubic { // first quadrant arc<br /> control1X: p.cx + p.rx; control1Y: p.cy + p.my<br /> control2X: p.cx + p.mx; control2Y: p.cy + p.ry<br /> x: p.cx; y: p.cy + p.ry<br /> }<br />}<br /></code>
  
 
Както може да видите, започваме пътя от втори квадрант. Целта е да първият елемент да е най-отдолу. Това е позицията и на текущият елелемнт.
 
Както може да видите, започваме пътя от втори квадрант. Целта е да първият елемент да е най-отдолу. Това е позицията и на текущият елелемнт.
  
==Довавяне на графичното оформление==
+
== Довавяне на графичното оформление ==
  
Вече трябва да имате основни познания как се създават пътища. За това минаваме на следващата стъпка графичното оформление. За целта ще използваме [https://www.gitorious.org/qt-training/qml-demos/trees/master/carousel/icons Трон подобни икони] ''[gitorious.org]'', които ще направим да изглеждат като 3D. Това се прави удивително лесно с <span class="caps">QML</span>.
+
Вече трябва да имате основни познания как се създават пътища. За това минаваме на следващата стъпка - графичното оформление. За целта ще използваме &quot;Трон подобни икони&amp;quot;:https://www.gitorious.org/qt-training/qml-demos/trees/master/carousel/icons, които ще направим да изглеждат като 3D. Това се прави удивително лесно с QML.
  
 
Първо, нека създаден необходимият модел. Започнахме с прост изкуствен модел и сега ще го заменим с истински. Това е кода за него:
 
Първо, нека създаден необходимият модел. Започнахме с прост изкуствен модел и сега ще го заменим с истински. Това е кода за него:
  
Използваме [http://developer.qt.nokia.com/doc/qt-4.7/qml-listmodel.html ListModel] ''[developer.qt.nokia.com]'' и го пълним с примерни данни. Свободни сме да дефинираме каквито искаме свойства за елементите. Ще използваме ''iconSource'' за иконите в менюто и ''title'' за да добавим заглавие по-късно. Новият ни делегат е базиран на компонента ''Image'' и изглежда по следният начин:
+
<code><br />// Model0.qml<br />import QtQuick 1.0
  
Кода не е много, нали? Но вече си има всичко необходимо за разкошно 3D меню. Имитираме 3D като намаляваме размера на иконите когато отивам към горната част на екрана. Намаляването на прозрачността също спомага за този ефект. Ако отворите ''Carousel4.qml'' в '''qmlviewer''', трябва да видите:
+
ListModel {<br /> ListElement { title: &quot;Calendar&amp;quot;; iconSource: &quot;icons/calendar.png&amp;quot; }<br /> ListElement { title: &quot;Setup&amp;quot;; iconSource: &quot;icons/develop.png&amp;quot; }<br /> ListElement { title: &quot;Internet&amp;quot;; iconSource: &quot;icons/globe.png&amp;quot; }<br /> ListElement { title: &quot;Messages&amp;quot;; iconSource: &quot;icons/mail.png&amp;quot; }<br /> ListElement { title: &quot;Music&amp;quot;; iconSource: &quot;icons/music.png&amp;quot; }<br /> ListElement { title: &quot;Call&amp;quot;; iconSource: &quot;icons/phone.png&amp;quot; }<br />}<br /></code>
  
[[Image:Carousel4.png|Carousel4.png]]
+
Използваме &quot;ListModel&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-listmodel.html и го пълним с примерни данни. Свободни сме да дефинираме каквито искаме свойства за елементите. Ще използваме ''iconSource'' за иконите в менюто и ''title'' за да добавим заглавие по-късно. Новият ни делегат е базиран на компонента ''Image'' и изглежда по следният начин:
  
==Добавяне на управление с клавиатурата==
+
<code><br />// Carouse5.qml<br />import QtQuick 1.0
  
Добаването на управление с клавиатурата е доста лесно. Първо добавяме следните три реда код, за да обработваме събития от клавиатурата:
+
Rectangle {<br /> width: 640<br /> height: 360<br /> color: &quot;black&amp;quot;<br /> PathView {<br /> id: view<br /> width: parent.width<br /> height: parent.height + y<br /> y: <s>33<br /> model: Menu0 {}<br /> delegate: Image {<br /> source: iconSource<br /> width: 64<br /> height: 64<br /> scale: 4. * y / parent.height<br /> z: y<br /> smooth: true<br /> opacity: scale / 2.<br /> }<br /> path: Ellipse {<br /> width: view.width<br /> height: view.height<br /> }<br /> }<br />}<br /></code>
 +
<br />Кода не е много, нали? Но вече си има всичко необходимо за разкошно 3D меню. Имитираме 3D като намаляваме размера на иконите когато отивам към горната част на екрана. Намаляването на прозрачността също спомага за този ефект. Ако отворите ''Carousel4.qml'' в '''qmlviewer''', трябва да видите:
 +
<br />[[Image:https://www.gitorious.org/qt-training/qml-demos/blobs/raw/b0cdec015684c0d2a7042f11ff53eca683c3dc52/carousel/Carousel4.png|Carousel4.png]]
 +
<br />h2. Добавяне на управление с клавиатурата
 +
<br />Добаването на управление с клавиатурата е доста лесно. Първо добавяме следните три реда код, за да обработваме събития от клавиатурата:
 +
<br /><code><br />// Carousel5.qml<br />…<br />PathView {<br /> …<br /> focus: true<br /> Keys.onLeftPressed: decrementCurrentIndex()<br /> Keys.onRightPressed: incrementCurrentIndex()<br /> …<br />}<br />…<br /></code>
 +
<br />Всички визуални елемент има свойство ''focus''. Само един елемент в даден момент може да има това свойство сложено на ''true'' и той е този който ще получи съобщения от клавиатурата. Използваме &quot;Keys&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-keys.html за да получаваме събития от клавиатурата. Можехме да използваме и по-сложният начин за обработка на съобщенията:<br /><code><br />Keys.onPressed: {<br /> if (event.key  Qt.Key_Left) decrementCurrentIndex()
 +
    else if (event.key  Qt.Key_Right) incrementCurrentIndex()<br /> event.accepted = true<br />}<br /></code>
 +
<br />Както виждате ние увеличаваме и намаляваме текущият индекс, когато се натисне бутон. Но кой точно е текущият елемент? Тъй като пътят може да приеме всякаква абстрактна форма, как може да знаем кой трябва да е тукещо активният елемент, ако изобщо има такъв? Чрез добавянето на следните редове код, можем да укажем на ''PathView'' да следи текущият елемент:
 +
<br /><code><br />…<br />PathView {<br /> …<br /> preferredHighlightBegin: 0<br /> preferredHighlightEnd: 0<br /> highlightRangeMode: PathView.StrictlyEnforceRange<br /> …<br />}<br />…<br /></code>
 +
<br />В нашият случай, решихме да направим първият елемент на пътя текущ. Сега вече трябва да можем да навигираме с клавиатурата като увеличаваме и намаляваме текущият елемент. Опитайте като отворите ''Carousel5.qml'' в '''qmlviewer'''.
 +
<br />h2. Донастройване
 +
<br />Накрая бихме желали да показваме и заглавието на текущият елемент. ''PathView'' има свойство ''highlightItem'', което бихме могли да използваме за подчертаване, но ние ще го използваме само за да изпишем &quot;текст&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-text.html. Тук също се вижда и как да свържете два компонента.<br /><code><br />…<br />PathView {<br /> id: view<br /> …<br />}<br />Text {<br /> id: label<br /> text: view.model.get(view.currentIndex).title<br /> color: &quot;paleturquoise&amp;quot;<br /> font.pixelSize: 16<br /> font.bold: true<br /> anchors.horizontalCenter: parent.horizontalCenter<br /> anchors.bottom: parent.bottom<br />}<br />…<br /></code>
 +
<br />Qt Quick предоставя богат набор от възможности за оформление на текста. Цвета ''paleturquoise'' е един от &quot;имената за цветове в SVG&amp;quot;:http://www.w3.org/TR/SVG/types.html#ColorKeywords.<br />Както може да видите, ние свързваме текста директно с заглавието от модела. Този начин на присвояване на стойности е бърз и лесен. Всеки път, когато ''currentIndex'' се промени, QML автоматично ще обнови текста с новата стойност. Но трябва да внимавате, може да възникне проблем. Не злоупотребявайте с директното свързване между различни обекти. На промер, когато решим да преименуваме ''title'' атрибута на модела на нещо друго, ще развалим всички свързвания, които включват ''title'' и няма да получим предупреждение, докато компонента не бъде създаден.
 +
<br />h2. Интернационализация
 +
<br />Вече говорихме по доста теми в този урок, който беше предназначен да бъде като бърза обиколка в Qt Quick, но ако започнем да говорим за неща като свързване със C++ код, пакетиране и разпространение към потребителите, това ще ни отклони от първоначалната ни цел да запазим нещата прости. Но има още една важна тема, която все още можем да включим</s> интернационализацията. Обикновено това е доста сложна тема, но Qt прави превода на приложения удивително лесен.
  
Всички визуални елемент има свойство ''focus''. Само един елемент в даден момент може да има това свойство сложено на ''true'' и той е този който ще получи съобщения от клавиатурата. Използваме [http://developer.qt.nokia.com/doc/qt-4.7/qml-keys.html Keys] ''[developer.qt.nokia.com]'' за да получаваме събития от клавиатурата. Можехме да използваме и по-сложният начин за обработка на съобщенията:<br />
+
Qt включва &quot;Qt Linguist&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/linguist-manual.html, който е мощен инструмент за превод на приложения. Същите процедури, използвани в C++ кода важат и в QML с изключение на &quot;няколко неща&amp;quot;:http://developer.qt.nokia.com/doc/qt-4.7/qdeclarative.html
  
Както виждате ние увеличаваме и намаляваме текущият индекс, когато се натисне бутон. Но кой точно е текущият елемент? Тъй като пътят може да приеме всякаква абстрактна форма, как може да знаем кой трябва да е тукещо активният елемент, ако изобщо има такъв? Чрез добавянето на следните редове код, можем да укажем на ''PathView'' да следи текущият елемент:
+
Текстовете, които трябва да бъдат преведени в QML, трябва да са сложени във функцията ''qsTr()''. Така инструмента '''lupdate''' ще може да извади тези текстове и да генерира XML файлове за превод (с разширение .ts). След това преводача, може да добави превод като използва '''Qt Linguist''' и след като са готови .ts се компилират до .qm файлове като се използва програмата '''lrelease'''. За да проверите превода просто подайте .qm файла на '''qmlviewer''' с опцията -translation.
  
В нашият случай, решихме да направим първият елемент на пътя текущ. Сега вече трябва да можем да навигираме с клавиатурата като увеличаваме и намаляваме текущият елемент. Опитайте като отворите ''Carousel5.qml'' в '''qmlviewer'''.
+
Има няколко проблема, за които трябва да знаете, така че нека да преведем заглавията на менюто. Може би си мислите, че можете просто да сложите ''title'' текста във функцията по този начин:
  
==Донастройване==
+
<code><br />ListModel {<br /> ListElement { title: qsTr(&quot;Calendar&amp;quot;); iconSource: &quot;icons/calendar.png&amp;quot; }<br /> …<br /></code>
  
Накрая бихме желали да показваме и заглавието на текущият елемент. ''PathView'' има свойство ''highlightItem'', което бихме могли да използваме за подчертаване, но ние ще го използваме само за да изпишем [http://developer.qt.nokia.com/doc/qt-4.7/qml-text.html текст] ''[developer.qt.nokia.com]''. Тук също се вижда и как да свържете два компонента.<br />
+
Но това няма да проработи, защото не е позволено изрази да са стойности на елемнтите. Има няколко начина да се заобиколи този проблем. Тъй като JavaScript функциите са позволени почти навсякъде, решаваме да пренапишем ''title'' като функция:
  
Qt Quick предоставя богат набор от възможности за оформление на текста. Цвета ''paleturquoise'' е един от [http://www.w3.org/TR/SVG/types.html#ColorKeywords имената за цветове в <span class="caps">SVG</span>] ''[w3.org]''.<br /> Както може да видите, ние свързваме текста директно с заглавието от модела. Този начин на присвояване на стойности е бърз и лесен. Всеки път, когато ''currentIndex'' се промени, <span class="caps">QML</span> автоматично ще обнови текста с новата стойност. Но трябва да внимавате, може да възникне проблем. Не злоупотребявайте с директното свързване между различни обекти. На промер, когато решим да преименуваме ''title'' атрибута на модела на нещо друго, ще развалим всички свързвания, които включват ''title'' и няма да получим предупреждение, докато компонента не бъде създаден.
+
<code><br />// Menu1.qml<br />import QtQuick 1.0
  
==Интернационализация==
+
ListModel {<br /> ListElement { iconSource: &quot;icons/calendar.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/develop.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/globe.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/mail.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/music.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/phone.png&amp;quot; }<br /> function title(index) {<br /> if (title[&quot;text&amp;quot;] === undefined) {<br /> title.text = [<br /> qsTr(&quot;Calendar&amp;quot;),<br /> qsTr(&quot;Setup&amp;quot;),<br /> qsTr(&quot;Internet&amp;quot;),<br /> qsTr(&quot;Messages&amp;quot;),<br /> qsTr(&quot;Music&amp;quot;),<br /> qsTr(&quot;Call&amp;quot;)<br /> ]<br /> }<br /> return title.text[index]<br /> }<br />}<br /></code>
  
Вече говорихме по доста теми в този урок, който беше предназначен да бъде като бърза обиколка в Qt Quick, но ако започнем да говорим за неща като свързване със C++ код, пакетиране и разпространение към потребителите, това ще ни отклони от първоначалната ни цел да запазим нещата прости. Но има още една важна тема, която все още можем да включим – интернационализацията. Обикновено това е доста сложна тема, но Qt прави превода на приложения удивително лесен.
+
Както може да видите, ние извикваме ''qsTr()'' за всеки елемент от модела, когато ''title()'' функцията е извикана за първи път. Разбира се такива конструкции се налагат само, когато трябва да се справите с превод на стойности в модел. Всички други текстове могат да бъдат преведени дитектно с ''qsTr()''.<br />Тъй като променихме дефиницията на модела, трябва да променим и местата, където се използваше старият вариант. За радост имаме късмет, че трябва да променим само един ред код:
  
Qt включва [http://developer.qt.nokia.com/doc/qt-4.7/linguist-manual.html Qt Linguist] ''[developer.qt.nokia.com]'', който е мощен инструмент за превод на приложения. Същите процедури, използвани в C++ кода важат и в <span class="caps">QML</span> с изключение на [http://developer.qt.nokia.com/doc/qt-4.7/qdeclarative.html няколко неща] ''[developer.qt.nokia.com]''
+
<code><br />text: view.model.title(view.currentIndex)<br /></code>
  
Текстовете, които трябва да бъдат преведени в <span class="caps">QML</span>, трябва да са сложени във функцията ''qsTr()''. Така инструмента '''lupdate''' ще може да извади тези текстове и да генерира <span class="caps">XML</span> файлове за превод (с разширение .ts). След това преводача, може да добави превод като използва '''Qt Linguist''' и след като са готови .ts се компилират до .qm файлове като се използва програмата '''lrelease'''. За да проверите превода просто подайте .qm файла на '''qmlviewer''' с опцията -translation.
+
Извикваме '''lupdate''', за да генерираме XML файловете за превод:
  
Има няколко проблема, за които трябва да знаете, така че нека да преведем заглавията на менюто. Може би си мислите, че можете просто да сложите ''title'' текста във функцията по този начин:
+
<code><br />lupdate . -ts Carousel_de.ts -codecfortr UTF-8<br /></code>
  
Но това няма да проработи, защото не е позволено изрази да са стойности на елемнтите. Има няколко начина да се заобиколи този проблем. Тъй като JavaScript функциите са позволени почти навсякъде, решаваме да пренапишем ''title'' като функция:
+
После отваряме файла с '''linguist''' и правим превода. След като сте съвршили, извиквате '''lrelease''':
  
Както може да видите, ние извикваме ''qsTr()'' за всеки елемент от модела, когато ''title()'' функцията е извикана за първи път. Разбира се такива конструкции се налагат само, когато трябва да се справите с превод на стойности в модел. Всички други текстове могат да бъдат преведени дитектно с ''qsTr()''.<br /> Тъй като променихме дефиницията на модела, трябва да променим и местата, където се използваше старият вариант. За радост имаме късмет, че трябва да променим само един ред код:
+
<code><br />lrelease Carousel_de.ts<br /></code>
 
 
Извикваме '''lupdate''', за да генерираме <span class="caps">XML</span> файловете за превод:
 
 
 
После отваряме файла с '''linguist''' и правим превода. След като сте съвршили, извиквате '''lrelease''':
 
  
 
'''lrelease''' ще генерита нов ''Carousel_de.qml''. Може да тествате превода като изпълните командата:
 
'''lrelease''' ще генерита нов ''Carousel_de.qml''. Може да тествате превода като изпълните командата:
  
===Categories:===
+
<code><br />usr/bin/qmlviewer -translation Carousel_de.qm Carousel7.qml<br /></code>
 
 
* [[:Category:Developing with Qt|Developing_with_Qt]]
 
** [[:Category:Developing with Qt::Qt Quick|Qt_Quick]]
 

Revision as of 06:30, 24 February 2015


Български English

[toc align_right="yes&quot; depth="2&quot;]

Как да направим въртележка с Qt Quick

Въведение

Този урок ще ви покаже как да създадете анимирано меню с елементи, въртящи се в псевдо 3D пространство. Също ще ви бъде показано как да разделите QML проекта на отделни модули и как да добавите поддръжка на различни езици с Qt Linguist.

Всичко, от което се нуждаете, за да изпълните инструкциите е qmlviewer. Ако използвате някоя от последните версии на Убунту, просто инсталирайте пакетите qt4-qmlviewer и libqt4-dev. Всички файлове от урока могат да бъдат намерени в "gitorious&quot;:https://www.gitorious.org/qt-training/qml-demos/trees/master/carousel .

Qt Quick трябва да бъде поне версия 1.0, която идва с Qt 4.7.1 и нагоре.

Запознаване с PathView

"PathView&quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-pathview.html взима елементи от модел и ги разполага по определен път. Пътят е геометрично дефиниран като последователност от участъци. Има три вида участъци: линии, квадратични и кубични криви на "Безие&quot;:http://en.wikipedia.org/wiki/Bezier_curve curves. За да придобиете опит в това, как да създавате пътища, нека започнем с най-обикновен участък под формата на права линия:

<br />// Carousel0.qml<br />import QtQuick 1.0

PathView {<br /> id: view<br /> width: 640<br /> height: 360<br /> model: 32<br /> delegate: Text { text: index }<br /> path: Path {<br /> startX: 0<br /> startY: 0<br /> PathLine { x: view.width; y: view.height }<br /> }<br />}<br />

PathView е нашият главен елемент. Слагайки числото 32 като модел, автоматично ще се генерират индекси за модела от 0 до 31. За всеки елемент от модела се създава по един делегат, за да се визуализира. Започваме с обикновено текстово поле, което показва индексите на елементите в модела. По-късно ще видим как се създават по-сложни делегати, но за сега нека да се фокусираме върху създаването на пътищата. Описанието на път изисква поне начална точка и един участък. В нашият случай започваме от (0, 0) и рисуваме праволинеен участък до долу в дясно. Като заредите файла в qmlviewer, трябва да получите подобен изход:
Carousel0.png

Когато плъзгате елементите, те реалистично ще се преместват. Забележете как те застават на фиксирани места. По подразбиране първият елемент е центриран в началната точка, а останалите са разпределени равномерно по дължината на пътя.

Добре, нека да усложним малко примера и да нарисуваме цял правоъгълник. Заменете описанието на пътя от предният пример със следното:

<br />// Carousel1.qml<br />…<br />property int pathMargin: 50<br />path: Path {<br /> startX: pathMargin<br /> startY: pathMargin<br /> PathLine { x: view.width - pathMargin; y: pathMargin }<br /> PathLine { x: view.width - pathMargin; y: view.height - pathMargin }<br /> PathLine { x: pathMargin; y: view.height - pathMargin }<br /> PathLine { x: path.startX; y: path.startY }<br />}<br />…<br />

Когато стартирате програмата, трябва да видите правоъгълник. Всеки "PathLine&quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-pathline.html започва от крайната точна на предният участък, така че ние трябва да зададем само крайните точни на всеки участък. За последният участък просто задаваме началната точка и така затваряме пътя. Създаваме наше си свойство pathMargin, за да си помогнем да дефинираме геометрията на пътя. Използването на потребителски свойства е най-лесният начин за създаване на допълнителни променливи в Qt Quick, но трябва да внимавате, защото те винаги са с публичен достъп.

Може да искате да напишете:

<br /><br />path: Path {<br /> property int pathMargin: 50<br /> startX: pathMargin<br /><br />

… но това не е възможно, защото Path компонента вече е дефиниран някъде другаде и не ние е позволено да добавяме нови свойства по време на изпълнение.

Създаване на кръг

След като се научихме да създаваме правоъгълник, нека да опитаме нещо по-трудно - кръг. Path не поддържа кръгли криви, така че ще трябва да използваме приближение чрез някои от следните варианти: линии, квадратични или кубични криви ви Безие. Тъй като това не е урок по аналитична геометрия, нека директно да преминем на решението - 4 кубични криви, като използваме "магическото число 0.551784&quot;:http://www.tinaja.com/glib/ellipse4.pdf. Погледнете кода:

<br />// Carousel2.qml<br />…<br />property int pathMargin: 50<br />property real rx: ry // view.width / 2 - pathMargin<br />property real ry: view.height / 2 - pathMargin<br />property real magic: 0.551784<br />property real mx: rx * magic<br />property real my: ry * magic<br />property real cx: view.width / 2<br />property real cy: view.height / 2<br />path: Path {<br /> startX: view.cx + view.rx; startY: view.cy<br /> PathCubic { // first quadrant arc<br /> control1X: view.cx + view.rx; control1Y: view.cy + view.my<br /> control2X: view.cx + view.mx; control2Y: view.cy + view.ry<br /> x: view.cx; y: view.cy + view.ry<br /> }<br /> PathCubic { // second quadrant arc<br /> control1X: view.cx - view.mx; control1Y: view.cy + view.ry<br /> control2X: view.cx - view.rx; control2Y: view.cy + view.my<br /> x: view.cx - view.rx; y: view.cy<br /> }<br /> PathCubic { // third quadrant arc<br /> control1X: view.cx - view.rx; control1Y: view.cy - view.my<br /> control2X: view.cx - view.mx; control2Y: view.cy - view.ry<br /> x: view.cx; y: view.cy - view.ry<br /> }<br /> PathCubic { // forth quadrant arc<br /> control1X: view.cx + view.mx; control1Y: view.cy - view.ry<br /> control2X: view.cx + view.rx; control2Y: view.cy - view.my<br /> x: view.cx + view.rx; y: view.cy<br /> }<br />}<br />…<br />

Това ни дава перфектен кръг:
Carousel2.png

Както може да видите, ние се нуждаем от по две контролни точки за всяка кубична крива. (Всички точки се дават в абсолютни координати.) Ако бяхме използвали квадратична крива, щяхме да се нуждаем само от една контролна точка. Контролните точки лежат извън кривата, но влияят на нейната форма. Може би сте запознати с концепцията от инструментите за работа с векторна графика.

Скриване на логиката

QML файла "може да се дефинира като преизползваем компонент&quot;:http://doc.qt.nokia.com/4.7/qml-extending-types.html#defining-new-components. Когато кода ви расте, вие обикновено искате да го разделите на логически блокове в отделни файлове, за да може да се използва многократно и да е по-лесен за четене. В нашият пример ще го разделим на:

<br />// Carousel3.qml<br />import QtQuick 1.0

PathView {<br /> id: view<br /> width: 640<br /> height: 360<br /> model: 32<br /> delegate: Text { text: index }<br /> path: Ellipse {<br /> width: view.width<br /> height: view.height<br /> }<br />}<br />

Нашият Ellipse компонент скрива сложната логика за апроксимиране на кръга и скалиране на елементите. Когато дефинираме наши компоненти, поризлизащи от вече съществуващи, можем да дефинираме и нови свойства. Компонента Ellipse съдържа следният код, който е леко променена версия на предният:

<br />// Ellipse.qml<br />import QtQuick 1.0

Path {<br /> id: p<br /> property real width: 200<br /> property real height: 200<br /> property real margin: 50<br /> property real cx: width / 2<br /> property real cy: height / 2<br /> property real rx: width / 2 - margin<br /> property real ry: height / 2 - margin<br /> property real mx: rx * magic<br /> property real my: ry * magic<br /> property real magic: 0.551784<br /> startX: p.cx; startY: p.cy + p.ry<br /> PathCubic { // second quadrant arc<br /> control1X: p.cx - p.mx; control1Y: p.cy + p.ry<br /> control2X: p.cx - p.rx; control2Y: p.cy + p.my<br /> x: p.cx - p.rx; y: p.cy<br /> }<br /> PathCubic { // third quadrant arc<br /> control1X: p.cx - p.rx; control1Y: p.cy - p.my<br /> control2X: p.cx - p.mx; control2Y: p.cy - p.ry<br /> x: p.cx; y: p.cy - p.ry<br /> }<br /> PathCubic { // forth quadrant arc<br /> control1X: p.cx + p.mx; control1Y: p.cy - p.ry<br /> control2X: p.cx + p.rx; control2Y: p.cy - p.my<br /> x: p.cx + p.rx; y: p.cy<br /> }<br /> PathCubic { // first quadrant arc<br /> control1X: p.cx + p.rx; control1Y: p.cy + p.my<br /> control2X: p.cx + p.mx; control2Y: p.cy + p.ry<br /> x: p.cx; y: p.cy + p.ry<br /> }<br />}<br />

Както може да видите, започваме пътя от втори квадрант. Целта е да първият елемент да е най-отдолу. Това е позицията и на текущият елелемнт.

Довавяне на графичното оформление

Вече трябва да имате основни познания как се създават пътища. За това минаваме на следващата стъпка - графичното оформление. За целта ще използваме "Трон подобни икони&quot;:https://www.gitorious.org/qt-training/qml-demos/trees/master/carousel/icons, които ще направим да изглеждат като 3D. Това се прави удивително лесно с QML.

Първо, нека създаден необходимият модел. Започнахме с прост изкуствен модел и сега ще го заменим с истински. Това е кода за него:

<br />// Model0.qml<br />import QtQuick 1.0

ListModel {<br /> ListElement { title: &quot;Calendar&amp;quot;; iconSource: &quot;icons/calendar.png&amp;quot; }<br /> ListElement { title: &quot;Setup&amp;quot;; iconSource: &quot;icons/develop.png&amp;quot; }<br /> ListElement { title: &quot;Internet&amp;quot;; iconSource: &quot;icons/globe.png&amp;quot; }<br /> ListElement { title: &quot;Messages&amp;quot;; iconSource: &quot;icons/mail.png&amp;quot; }<br /> ListElement { title: &quot;Music&amp;quot;; iconSource: &quot;icons/music.png&amp;quot; }<br /> ListElement { title: &quot;Call&amp;quot;; iconSource: &quot;icons/phone.png&amp;quot; }<br />}<br />

Използваме "ListModel&quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-listmodel.html и го пълним с примерни данни. Свободни сме да дефинираме каквито искаме свойства за елементите. Ще използваме iconSource за иконите в менюто и title за да добавим заглавие по-късно. Новият ни делегат е базиран на компонента Image и изглежда по следният начин:

<br />// Carouse5.qml<br />import QtQuick 1.0

Rectangle {<br /> width: 640<br /> height: 360<br /> color: &quot;black&amp;quot;<br /> PathView {<br /> id: view<br /> width: parent.width<br /> height: parent.height + y<br /> y: <s>33<br /> model: Menu0 {}<br /> delegate: Image {<br /> source: iconSource<br /> width: 64<br /> height: 64<br /> scale: 4. * y / parent.height<br /> z: y<br /> smooth: true<br /> opacity: scale / 2.<br /> }<br /> path: Ellipse {<br /> width: view.width<br /> height: view.height<br /> }<br /> }<br />}<br />


Кода не е много, нали? Но вече си има всичко необходимо за разкошно 3D меню. Имитираме 3D като намаляваме размера на иконите когато отивам към горната част на екрана. Намаляването на прозрачността също спомага за този ефект. Ако отворите Carousel4.qml в qmlviewer, трябва да видите:
Carousel4.png
h2. Добавяне на управление с клавиатурата
Добаването на управление с клавиатурата е доста лесно. Първо добавяме следните три реда код, за да обработваме събития от клавиатурата:


<br />// Carousel5.qml<br />…<br />PathView {<br /> …<br /> focus: true<br /> Keys.onLeftPressed: decrementCurrentIndex()<br /> Keys.onRightPressed: incrementCurrentIndex()<br /> …<br />}<br />…<br />

Всички визуални елемент има свойство focus. Само един елемент в даден момент може да има това свойство сложено на true и той е този който ще получи съобщения от клавиатурата. Използваме "Keys&quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-keys.html за да получаваме събития от клавиатурата. Можехме да използваме и по-сложният начин за обработка на съобщенията:
<br />Keys.onPressed: {<br /> if (event.key  Qt.Key_Left) decrementCurrentIndex()
    else if (event.key  Qt.Key_Right) incrementCurrentIndex()<br /> event.accepted = true<br />}<br />


Както виждате ние увеличаваме и намаляваме текущият индекс, когато се натисне бутон. Но кой точно е текущият елемент? Тъй като пътят може да приеме всякаква абстрактна форма, как може да знаем кой трябва да е тукещо активният елемент, ако изобщо има такъв? Чрез добавянето на следните редове код, можем да укажем на PathView да следи текущият елемент:


<br /><br />PathView {<br /> <br /> preferredHighlightBegin: 0<br /> preferredHighlightEnd: 0<br /> highlightRangeMode: PathView.StrictlyEnforceRange<br /> <br />}<br /><br />


В нашият случай, решихме да направим първият елемент на пътя текущ. Сега вече трябва да можем да навигираме с клавиатурата като увеличаваме и намаляваме текущият елемент. Опитайте като отворите Carousel5.qml в qmlviewer.
h2. Донастройване


Накрая бихме желали да показваме и заглавието на текущият елемент. PathView има свойство highlightItem, което бихме могли да използваме за подчертаване, но ние ще го използваме само за да изпишем "текст&quot;:http://developer.qt.nokia.com/doc/qt-4.7/qml-text.html. Тук също се вижда и как да свържете два компонента.
<br /><br />PathView {<br /> id: view<br /> <br />}<br />Text {<br /> id: label<br /> text: view.model.get(view.currentIndex).title<br /> color: &quot;paleturquoise&amp;quot;<br /> font.pixelSize: 16<br /> font.bold: true<br /> anchors.horizontalCenter: parent.horizontalCenter<br /> anchors.bottom: parent.bottom<br />}<br /><br />


Qt Quick предоставя богат набор от възможности за оформление на текста. Цвета paleturquoise е един от "имената за цветове в SVG&quot;:http://www.w3.org/TR/SVG/types.html#ColorKeywords.
Както може да видите, ние свързваме текста директно с заглавието от модела. Този начин на присвояване на стойности е бърз и лесен. Всеки път, когато currentIndex се промени, QML автоматично ще обнови текста с новата стойност. Но трябва да внимавате, може да възникне проблем. Не злоупотребявайте с директното свързване между различни обекти. На промер, когато решим да преименуваме title атрибута на модела на нещо друго, ще развалим всички свързвания, които включват title и няма да получим предупреждение, докато компонента не бъде създаден.
h2. Интернационализация
Вече говорихме по доста теми в този урок, който беше предназначен да бъде като бърза обиколка в Qt Quick, но ако започнем да говорим за неща като свързване със C++ код, пакетиране и разпространение към потребителите, това ще ни отклони от първоначалната ни цел да запазим нещата прости. Но има още една важна тема, която все още можем да включим</s> интернационализацията. Обикновено това е доста сложна тема, но Qt прави превода на приложения удивително лесен.

Qt включва "Qt Linguist&quot;:http://developer.qt.nokia.com/doc/qt-4.7/linguist-manual.html, който е мощен инструмент за превод на приложения. Същите процедури, използвани в C++ кода важат и в QML с изключение на "няколко неща&quot;:http://developer.qt.nokia.com/doc/qt-4.7/qdeclarative.html

Текстовете, които трябва да бъдат преведени в QML, трябва да са сложени във функцията qsTr(). Така инструмента lupdate ще може да извади тези текстове и да генерира XML файлове за превод (с разширение .ts). След това преводача, може да добави превод като използва Qt Linguist и след като са готови .ts се компилират до .qm файлове като се използва програмата lrelease. За да проверите превода просто подайте .qm файла на qmlviewer с опцията -translation.

Има няколко проблема, за които трябва да знаете, така че нека да преведем заглавията на менюто. Може би си мислите, че можете просто да сложите title текста във функцията по този начин:

<br />ListModel {<br /> ListElement { title: qsTr(&quot;Calendar&amp;quot;); iconSource: &quot;icons/calendar.png&amp;quot; }<br /> <br />

Но това няма да проработи, защото не е позволено изрази да са стойности на елемнтите. Има няколко начина да се заобиколи този проблем. Тъй като JavaScript функциите са позволени почти навсякъде, решаваме да пренапишем title като функция:

<br />// Menu1.qml<br />import QtQuick 1.0

ListModel {<br /> ListElement { iconSource: &quot;icons/calendar.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/develop.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/globe.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/mail.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/music.png&amp;quot; }<br /> ListElement { iconSource: &quot;icons/phone.png&amp;quot; }<br /> function title(index) {<br /> if (title[&quot;text&amp;quot;] === undefined) {<br /> title.text = [<br /> qsTr(&quot;Calendar&amp;quot;),<br /> qsTr(&quot;Setup&amp;quot;),<br /> qsTr(&quot;Internet&amp;quot;),<br /> qsTr(&quot;Messages&amp;quot;),<br /> qsTr(&quot;Music&amp;quot;),<br /> qsTr(&quot;Call&amp;quot;)<br /> ]<br /> }<br /> return title.text[index]<br /> }<br />}<br />

Както може да видите, ние извикваме qsTr() за всеки елемент от модела, когато title() функцията е извикана за първи път. Разбира се такива конструкции се налагат само, когато трябва да се справите с превод на стойности в модел. Всички други текстове могат да бъдат преведени дитектно с qsTr().
Тъй като променихме дефиницията на модела, трябва да променим и местата, където се използваше старият вариант. За радост имаме късмет, че трябва да променим само един ред код:

<br />text: view.model.title(view.currentIndex)<br />

Извикваме lupdate, за да генерираме XML файловете за превод:

<br />lupdate . -ts Carousel_de.ts -codecfortr UTF-8<br />

После отваряме файла с linguist и правим превода. След като сте съвршили, извиквате lrelease:

<br />lrelease Carousel_de.ts<br />

lrelease ще генерита нов Carousel_de.qml. Може да тествате превода като изпълните командата:

<br />usr/bin/qmlviewer -translation Carousel_de.qm Carousel7.qml<br />