Модел-изглед в QML
Не винаги готовите изображения са идеални. Обмислете компонентите, които ви позволяват да създадете напълно персонализиран изглед и да постигнете голяма гъвкавост при изграждането на интерфейс. И малък бонус от мен за търпеливите читатели :)
1. Изглед на пътя
Този компонент отчасти принадлежи към същата група готови дисплеи, но оформлението на елементите се контролира изцяло от потребителя. Това се постига чрез факта, че компонентът ви позволява да подредите елементи по определен път, който е съставен от прави линии, криви и дъги. Пътят може да бъде затворен, но не е задължително. По пътя можем също да манипулираме свойствата на елементите. Например, можете да накарате елемент да стане по-голям на определено място и да изглежда по-близо до потребителя. В допълнение към това, тези елементи, които трябва да изглеждат по-далеч от потребителя, могат да бъдат направени полупрозрачни. Като цяло има много възможности за персонализиране на външния вид на елементите.
Основната цел на PathView е не само да показва данни, но и да ги направи да изглеждат визуално привлекателни. Именно с помощта на този компонент се правят неща като CoverFlow (популярна опция за показване на обложки на албуми в мултимедийни плейъри).
1) прост пример
Нека започнем с прост пример, поставяне на елементи по крива (за да бъдем точни, използва се квадратична крива на Безие)
Пътят се описва с помощта на обект от тип Path, в който поставяме обекти, които описват части от този път. В нашия случай пътят се състои от един участък под формата на крива.
Параметрите startX и startY описват началните координати на пътя. Свършва къдепоследният раздел завършва. За секцията, напротив, не се задава началото, а краят, като се използват параметрите x и y. В нашия случай кривата се изгражда от три точки: освен края и началото е необходима още една координата, от която зависи каква ще бъде чупката. Свойствата controlX и controlY са отговорни за неговите координати. За участък от пътя координатите се задават спрямо родителя, т.е. пътен обект. Има и специални свойства, които ви позволяват да задавате координати спрямо началото на пътя. Такива свойства имат префикс относителен (например relativeControlY).
Да видим какво имаме:

Тъй като всички елементи са поставени в PathView, можем да плъзгаме елементите с мишката и те ще се движат по пътя.
2) затворен път
В предишния пример пътят не е затворен. След като даден елемент достигне своя път, той се появява в началото. Не е много по-трудно да направите пътя затворен. За да направите това, е необходимо координатите на началото и края му да съвпадат. Обектът Path дори има специално затворено свойство, което отразява дали е затворен.
Нека преработим малко първия пример и направим затворен път от две криви на Безие (PathQuad):
Всеки елемент на пътя започва там, където свършва предишният. Последният ни сегмент завършва там, където започва цялото пътуване. В резултат на това получаваме следната фигура:

3) елементи на пътя
В допълнение към разглежданата крива, QtQuick има кубични криви на Безие - същото като квадратичните, но с две контролни точки (PathCubic), крива с произволен брой точки (PathCurve), дъга - т.е. част от кръг (PathArk) и права линия (PathLine). Освен това можете да дефинирате кривата с SVG описание, като използвате компонента PathSvg. Всички тези компоненти могат да се комбинират инаправи правилния път от тях.
Има и допълнителни компоненти, които не контролират разположението на елементите и техните параметри. Един от тях е PathPercent, който ви позволява да контролирате разпределението на елементите по секциите на пътя. По подразбиране елементите са разпределени равномерно, но с помощта на този компонент можете да посочите за части от пътя каква част от елементите, колко ще бъдат разположени там. За да направите това, след секцията с пътя се поставя обектът PathPercent, чийто параметър стойност съдържа част от елементите за този път (например 0,5 за половината от елементите).
Нека да разгледаме това с пример:
Правим път с две дъги и една права линия в средата. В същото време се уверяваме, че елементите са концентрирани в крайните части на пътя. И се оказва, че централната секция съдържа само един елемент:

Друг допълнителен елемент на пътя е PathAttribute, който ви позволява да контролирате параметрите на елементите в зависимост от тяхното местоположение на пътя. В делегата тези опции ще бъдат достъпни чрез прикачените свойства на PathView.name, където името е указано с помощта на свойството name.
PathAttribute определя стойностите на параметрите в точката на пътя, където се намира. Стойностите на параметрите на елементите в секцията на пътя, която е между два обекта на PathAttribute, ще преминат плавно от стойностите на един PathAttribute към друг. Ако няма такъв обект от едната страна, тогава ще бъдат взети нулеви стойности.
Нека направим централния обект два пъти по-голям и направим външните елементи полупрозрачни:
И получаваме елементи, в които размерът и прозрачността се променят плавно:

Ако не се нуждаете от плавен преход, а просто трябва да направите елементи с различни размери, можете да обградите всеки такъвучастък от пътя с обекти PathView, а между съседни участъци вмъкнете допълнителни участъци от пътя с нулева дължина, по които ще се извърши преходът от една стойност на параметър към друга. Но поради нулевия размер там няма елементи и това няма да се вижда.
За да демонстрираме, нека модифицираме малко предишния пример и направим всяка от трите части на пътя заобиколена от обекти PathAttribute, а между тези части поставяме обекти PathLine с нулева дължина.
В резултат на това получаваме малки полупрозрачни елементи в краищата и един голям и непрозрачен елемент в центъра:

4) CoverFlow
В началото на раздела споменах CoverFlow. Като бонус за тези, които са чели до тук, малък пример за внедряване :)
Първо нека видим резултата и след това ще анализираме изпълнението. И завършихме с нещо подобно:

Завъртаме всички елементи с изключение на централния около оста Y. За да направим това, задаваме делегатите на ротационна трансформация с помощта на компонента Rotation. В свойството axis трябва да зададете 1 за онези оси, около които обектът ще се върти. За елементите променяме няколко параметъра: ъгъл на завъртане, местоположение по оста Z и точка на въртене (начало). С ъгъла всичко е просто и очевидно: елементите, които са отляво, се завъртат на 60 градуса, а тези отдясно, съответно, с -60. Но на останалите параметри си струва да се спрем по-подробно.
Координатата Z определя кой елемент ще бъде "отгоре", т.е. когато два обекта се пресичат някъде, обектът с по-малката Z ще бъде припокрит от обекта с по-голямата Z координата. По подразбиране в PathView елемент с по-висок индекс се припокрива с предишния. В CoverFlow за елементи отляво трябва да иматенапротив: „отгоре“ са онези елементи, които са по-близо до центъра. Ако не се направи нищо, тогава последният елемент ще припокрие предпоследния, който от своя страна ще припокрие елемента преди него и т.н. Следователно променяме Z координатата, така че колкото по-далеч е елементът от центъра, толкова „по-нисък“ е той. В нашия пример размерите са такива, че елементите не се припокриват, но ако леко намалим ширината на прозореца, тогава припокриването веднага ще се появи:

И накрая, повратната точка. Задаваме точка на нашия правоъгълник, около която ще се извърши въртенето. По подразбиране това е горният ляв ъгъл, т.е. точка с координати (0, 0). защото въртим елемента около оста Y, тогава самата Y координата няма значение тук. Но си струва да обърнете внимание на X. В случай на елементи, които са от лявата страна, задаваме тази координата на 0 и завъртаме елемента около левия ръб и се оказва, че десният ръб визуално става по-далеч. Ако направим същото за елементите отдясно, се оказва, че обръщаме елементите отляво „от себе си“, а елементите отдясно - „към себе си“, т.е. левият ръб ще бъде близо, а десният ръб ще бъде още по-близо, а дясната страна ще бъде по-голяма. В резултат на това получаваме такава ситуация, че елементите отляво и отдясно ще бъдат с различни размери, които изобщо не ни трябват. Завъртаме всички елементи „далеч от нас“ и за това в елементите отдясно изместваме точката на въртене в горния десен ъгъл, така че да се въртят около десния си ръб.
В предишните примери PathView показваше всички елементи от модела. Броят на елементите, показвани едновременно, може да бъде ограничен с помощта на параметъра pathItemCount. Тук го поставих на шест.
Обобщавайки, можем да кажем, че с помощта на QML такъв популярен начин за представяне на данни днес като CoverFlow е доста просто реализиран, когатопомощ на елементи от стандартната библиотека.
Резюме
PathView е компонент, фокусиран основно върху създаването на атрактивен интерфейс. Този инструмент има голяма гъвкавост, позволявайки ви да поставяте елементи не само в права линия, но и по произволен път, както и да променяте параметрите на делегата в зависимост от това в коя част от пътя се намира.
2. Вашата презентация
QML ни дава инструментите, за да направим нашето представяне, ако е необходимо. Това не е много трудно и се изпълнява чрез комбиниране на прости елементи.
Първо трябва да създадем делегирани обекти за всеки елемент от модела. За целта ще използваме специален компонент - Повторител. Занимава се изключително със създаването на елементи, без позициониране и т.н. той не прави неща. Използва се по абсолютно същия начин като компонентите *View: ние му даваме модел и делегат и той ще създаде екземпляри на делегата за всеки елемент от модела.
За позициониране можем да използваме елементите Row и Column, в които ще поставим нашия Repeater. Елементите, създадени с Repeater, стават деца на своя родител, т.е. в този случай Ред или Колона, които позиционират своите елементи съответно като ред или колона.
Единствената останала задача е навигацията. Ако има толкова много елементи, че всички няма да се поберат в отделеното им пространство, трябва да внедрим превъртане на елементите. Това става с помощта на компонента Flickable, който управлява колелото на мишката и жестовете на сензорния екран или същата мишка и превърта елементите.
Например, нека направим елементите не вертикално, а хоризонтално:
Задаваме височината на елемента Row да бъде фиксирана и ширината автоматично ще бъде фиксиранапромяна, в зависимост от общата ширина на неговите деца. За Flickable задаваме contentWidth, което е, както може би се досещате, ширината на неговото съдържание. Ако е по-голяма от ширината на самия Flicable, това ще им позволи да превъртат. В нашия пример последният елемент просто не пасва и можем да се уверим, че превъртането работи.

Както можете да видите, библиотеката QtQuick ви позволява да правите без да използвате готови изгледи и да създавате свои собствени от прости компоненти, които също ще работят добре.
Стандартните компоненти ви позволяват да реализирате изгледи от различни типове: от таблици до елементи, подредени по произволен начин. В допълнение към готовите изгледи, можете да създадете напълно свои собствени от основни компоненти.
PathView е предназначен да създаде дисплей, фокусиран върху красив външен вид и анимация и ви позволява да зададете траекторията на движение на елементите, да променяте параметрите на елемента в зависимост от местоположението му и плътността на елементите в различните части на пътя.
Hardcore conf в C++. Каним само професионалисти.