Rapido, intuitivo, potente: Qt Quick all'assalto delle User Interfaces Alessandro La Rosa http://www.jappit.com
Di che si parla? <ul><li>Dove, quando e come usare Qt Quick? </li></ul><ul><li>Strumenti di sviluppo </li></ul><ul><li>QML...
Speaker <ul><li>Sviluppatore freelance </li></ul><ul><ul><li>Personal website:  http://www.jappit.com   </li></ul></ul><ul...
Cos'è Qt Quick? <ul><li>Qt Quick è un insieme di tecnologie che permette il  </li></ul><ul><li>QML : linguaggio di markup ...
Strumenti di sviluppo <ul><li>Qt SDK:  http://qt.nokia.com/downloads/   </li></ul><ul><li>Versione 1.1 rilasciata il 4 Mag...
Qt SDK Qt Creator Qt Designer Qt Simulator
Devices <ul><li>Qt Everywhere!  </li></ul><ul><li>Symbian^3 </li></ul><ul><li>Symbian^1 </li></ul><ul><li>Maemo </li></ul>...
QML Dichiarativo Aspetto e comportamento UI  Struttura ad albero (DOM-like) Estendibile con QML o C++
QML – Basics import   QtQuick   1.0 Rectangle { width: 200; height: 200  color: &quot;blue&quot; Image { anchors.centerIn:...
QML – Basics import QtQuick 1.0 Rectangle   { width :   200;   height :   200   color :   &quot;blue&quot; Image { anchors...
QML - Elementi <ul><li>Divisi in visuali e non visuali </li></ul><ul><li>Elementi visuali discendono da  Item </li></ul><u...
QML – Proprietà Rectangle   { id :   root  (4) width :   360;   height :   360  (1) property   variant   myList:   [ &quot...
QML – Proprietà Rectangle   { id :   root width :   360;   height :   360 property   variant   myList:   [ &quot;QML&quot;...
Alcune proprietà fondamentali <ul><li>Ereditate da  Item </li></ul><ul><ul><ul><li>scale : real </li></ul></ul></ul><ul><u...
Il property Binding <ul><li>Proprietà associate ad espressioni JavaScript </li></ul><ul><li>Assegnamento QML != Assegnamen...
Comporre la User Interface <ul><li>QML offre 3 modi diversi per posizionare elementi nella User Interface: </li></ul><ul><...
Layout basati su anchor Rectangle   { width :   200;   height :   200;   color :   &quot;red&quot; Rectangle   { width :  ...
Elementi Positioner Column   { anchors.centerIn :   parent Rectangle   { width :   100;   height :   100;   color :   &quo...
Proprietà x, y, width e height Rectangle   { width :   200;   height :   200;   color :   &quot;red&quot; Rectangle   { co...
Interazione Utente – Touch <ul><li>MouseArea : elemento non visuale </li></ul><ul><li>Aggiunto ad elementi visuali con  an...
Interazione Utente – Touch <ul><li>Interazione  property -based </li></ul><ul><ul><ul><li>containsMouse, pressed, pressedB...
Interazione Utente – Tastiera <ul><li>Keys  attached property per elementi visuali </li></ul><ul><li>Eventi intercettati d...
Gestione del focus <ul><li>Proprietà  activeFocus  permette di controllare se un Item ha focus attivo </li></ul><ul><li>El...
Estendere QML con nuovi componenti <ul><li>Componente: elemento QML riutilizzabile, scritto in QML </li></ul><ul><li>Codic...
Estendere QML con nuovi componenti <ul><li>Che succede settando il valore della proprietà text? </li></ul><ul><ul><ul><li>...
Property Alias <ul><li>Connessione tra 2 proprietà </li></ul><ul><li>Binding != Alias </li></ul><ul><li>Bidirezionale </li...
Aggiungere segnali ad un componente <ul><li>Definiti con la sintassi: </li></ul><ul><ul><ul><li>signal <name>[(<type> <val...
Definire metodi per un componente RoundedButton.qml Rectangle   { radius :   5;   color :   &quot;blue&quot; property   st...
Componenti e moduli <ul><li>Un modulo rappresenta un insieme di file QML importabili in una applicazione QML </li></ul><ul...
Versioning e named imports qmldir metadata file Triangle 1.0 Triangle.qml Circle 1.0 Circle.qml Ellipsis 1.0 Ellipsis.qml ...
Gestire e visualizzare dati <ul><li>DataModel </li></ul><ul><li>Metodi per inserimento/rimozione dinamica di dati </li></u...
Visualizzazione di un Data Model ListModel   { id :   myModel ListElement   { colore :   &quot;blue&quot; } ListElement   ...
Visualizzazione efficiente: le Views ListModel   { id :   myModel ListElement   { nome :   &quot;Symbian&quot; } ListEleme...
Altri Data Model... VisualItemModel   { id :   myModel Rectangle   { width :   800;   height :   100;   color :   &quot;re...
Animare la User Interface <ul><li>Variazione progressiva delle proprietà di un elemento </li></ul><ul><li>Classe di base: ...
Animazione esplicita Item   { width :   360;   height :   360 Image   { width :   64;   height :   64 source :   &quot;myI...
Animazione standalone Item   { width :   360;   height :   360 Image   { id :   myImage;   width :   64;   height :   64; ...
Animazione al variare di una proprietà Item   { width :   360;   height :   360 Image   { id :   myImage width :   64;   h...
Animazione in un signal handler Item   { width :   360;   height :   360 Image   { id :   myImage width :   64;   height :...
Gestire la UI tramite stati <ul><li>Rappresentati dall'elemento  State </li></ul><ul><li>Definiscono stati diversi della U...
Definizione di uno stato Rectangle   {   id :   root ;  width :   360; height :   360 ;  color :   &quot;red&quot; states ...
Attivazione di uno stato Rectangle   {   id :   root ;  width :   360; height :   360 ;  color :   &quot;red&quot; states ...
Condizioni di uno stato Rectangle   {   id :   root ;  width :   360;   height :   360 ;  color :   &quot;red&quot; states...
Transizioni tra stati Rectangle   { [...] transitions :   [ Transition   { from :   &quot;&quot; to :   &quot;pressed&quot...
Animazioni parallele e sequenziali Image   { id :   myImage width :   64;   height :   64;   source :   &quot;qt-logo.png&...
QML e JavaScript <ul><li>Inline e librerie esterne </li></ul><ul><li>Named Imports:  import   &quot;js/MyLibrary.js&quot; ...
Esempio di libreria JavaScript function   startup()   { // cambio il colore dell'elemento con id “root”   root.color   =  ...
Estendere QML in C++ <ul><li>Implementare nuovi Data Model </li></ul><ul><li>Accesso a funzionalità Qt </li></ul><ul><li>C...
Utilizzo di un tipo implementato in C++ import   QtQuick   1.0 import   FormeGeometriche   1.0 Rectangle   { width :   300...
Implementiamo il nuovo visual item triangleitem.h #include   <QDeclarativeItem> class   Triangletem   :   public   QDeclar...
Definire nuove proprietà triangleitem .h class   TriangleItem   :   public   QDeclarativeItem { Q_OBJECT Q_PROPERTY  ( QCo...
Costruttore e metodo paint() triangleitem.cpp TriangleItem  :: TriangleItem ( QDeclarativeItem   *parent)   : QDeclarative...
Implementiamo setter e getter triangleitem.cpp const   QColor   & TriangleItem :: color ()   const   { return   m_color ; ...
Registrazione del nuovo tipo main.cpp int   main (int   argc,   char   *argv[]) { QApplication   app(argc,   argv); qmlReg...
Aggiungere metodi richiamabili da QML triangleitem.h class   TriangleItem   :   public   QDeclarativeItem { public : Q_INV...
Aggiungere proprietà custom triangleitem.h class   TriangleItem   :   public   QDeclarativeItem {   Q_ENUMS  ( Style ) pub...
Utilizzo di proprietà  enum triangleitem.cpp void   TriangleItem :: paint ( QPainter   *painter, const   QstyleOptionGraph...
Velocizziamo lo sviluppo <ul><li>Export automatico da Photoshop e GIMP a QML </li></ul><ul><li>Qt Quick Components: set di...
Plugin QML di Qt Mobility <ul><li>Offrono accesso ad API Qt con sintassi dichiarativa: </li></ul><ul><ul><ul><li>Contacts ...
Grazie!
Upcoming SlideShare
Loading in...5
×

Rapido, intuitivo, potente: Qt Quick all'assalto delle User Interfaces

1,188

Published on

Grazie a QML e JavaScript, lo sviluppo di User Interfaces in applicazioni Qt è più facile che mai. Questa presentazione introduce gli sviluppatori alla tecnologia, alle sue funzionalità principali, e alle possibilità di interazione con codice C++.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,188
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Rapido, intuitivo, potente: Qt Quick all'assalto delle User Interfaces"

  1. 1. Rapido, intuitivo, potente: Qt Quick all'assalto delle User Interfaces Alessandro La Rosa http://www.jappit.com
  2. 2. Di che si parla? <ul><li>Dove, quando e come usare Qt Quick? </li></ul><ul><li>Strumenti di sviluppo </li></ul><ul><li>QML, JavaScript </li></ul><ul><li>Elementi, proprietà, binding </li></ul><ul><li>Animazioni </li></ul><ul><li>Interazione Utente </li></ul><ul><li>Stati e transizioni </li></ul><ul><li>Definizione di nuovi componenti </li></ul><ul><li>Presentazione dei dati </li></ul><ul><li>Integrazione con C++ </li></ul>
  3. 3. Speaker <ul><li>Sviluppatore freelance </li></ul><ul><ul><li>Personal website: http://www.jappit.com </li></ul></ul><ul><li>Forum Nokia Champion dal 2008 </li></ul><ul><ul><li>Wiki articles: http://bit.ly/FNJappitWiki </li></ul></ul><ul><ul><li>Blog su Forum Nokia: http://bit.ly/FNJappit </li></ul></ul><ul><li>Qt Ambassador </li></ul><ul><ul><li>QML Bites: http://bit.ly/qmlbites </li></ul></ul><ul><li>Blogger </li></ul><ul><ul><li>http://blog.ovi.com/dailyapp/global </li></ul></ul><ul><ul><li>http://www.nokiadevs.com </li></ul></ul>
  4. 4. Cos'è Qt Quick? <ul><li>Qt Quick è un insieme di tecnologie che permette il </li></ul><ul><li>QML : linguaggio di markup </li></ul><ul><ul><li>Scripting language: JavaScript </li></ul></ul><ul><li>Insieme di elementi di User Interface </li></ul><ul><ul><li>Liste, Immagini, Campi editabili, … </li></ul></ul><ul><ul><li>Elementi funzionali </li></ul></ul><ul><li>Runtime </li></ul><ul><ul><li>Modulo QtDeclarative </li></ul></ul>
  5. 5. Strumenti di sviluppo <ul><li>Qt SDK: http://qt.nokia.com/downloads/ </li></ul><ul><li>Versione 1.1 rilasciata il 4 Maggio </li></ul><ul><li>Qt Creator 2.1 (2.2 già rilasciata) </li></ul><ul><ul><ul><li>Include Qt Designer </li></ul></ul></ul><ul><li>Apps Qt Quick su Ovi Store </li></ul><ul><li>Supporto Qt 4.7.3 per Desktop e Symbian </li></ul><ul><li>Qt Mobility 1.1 </li></ul><ul><li>Qt Simulator </li></ul><ul><li>Remote compiler </li></ul><ul><ul><ul><li>Supporto OS X e Linux </li></ul></ul></ul>
  6. 6. Qt SDK Qt Creator Qt Designer Qt Simulator
  7. 7. Devices <ul><li>Qt Everywhere! </li></ul><ul><li>Symbian^3 </li></ul><ul><li>Symbian^1 </li></ul><ul><li>Maemo </li></ul><ul><li>MeeGo </li></ul>v
  8. 8. QML Dichiarativo Aspetto e comportamento UI Struttura ad albero (DOM-like) Estendibile con QML o C++
  9. 9. QML – Basics import QtQuick 1.0 Rectangle { width: 200; height: 200 color: &quot;blue&quot; Image { anchors.centerIn: parent source: &quot;qt-logo.png&quot; } } <ul><li>Il modulo QtQuick va caricato tramite import </li></ul><ul><li>Il numero di versione garantisce consistenza delle funzionalità tra release differenti di un modulo </li></ul>
  10. 10. QML – Basics import QtQuick 1.0 Rectangle { width : 200; height : 200 color : &quot;blue&quot; Image { anchors.centerIn: parent source: &quot;qt-logo.png&quot; } } <ul><li>La root di un albero QML può essere qualunque elemento </li></ul><ul><li>Corpo di un elemento può contenere proprietà, elementi figli, funzioni JavaScript, … </li></ul><ul><li>Proprietà definite nel formato chiave : valore </li></ul>
  11. 11. QML - Elementi <ul><li>Divisi in visuali e non visuali </li></ul><ul><li>Elementi visuali discendono da Item </li></ul><ul><ul><ul><li>Image , Text , TextInput , ... </li></ul></ul></ul><ul><li>Elementi non visuali utili per definire behavior, animazioni, etc.. </li></ul><ul><ul><ul><li>Animation , Behavior , ListModel , Timer , Repeater , ... </li></ul></ul></ul><ul><li>Possono avere proprietà </li></ul><ul><li>Possibilità di definire elementi custom </li></ul>
  12. 12. QML – Proprietà Rectangle { id : root (4) width : 360; height : 360 (1) property variant myList: [ &quot;QML&quot; , &quot;Rocks!&quot; , 3] (2) onWidthChanged : console.log( &quot;Proprietà di tipo Script&quot; ) Text { text : root.myList[0] + &quot; &quot; + parent.myList[1]; font : { bold : false; italic : true} (3) } } <ul><li>Separate da punto e virgola oppure line-break </li></ul><ul><li>Proprietà custom </li></ul><ul><li>Grouped properties </li></ul><ul><li>La proprietà “id” </li></ul>
  13. 13. QML – Proprietà Rectangle { id : root width : 360; height : 360 property variant myList: [ &quot;QML&quot; , &quot;Rocks!&quot; , 3] onWidthChanged : console.log( &quot;Proprietà di tipo Script&quot; ) Text { text : root.myList[0] + &quot; &quot; + parent.myList[1]; font : { bold : false; italic : true} } } <ul><li>Segnali e notifiche </li></ul><ul><li>Tipi: </li></ul><ul><ul><ul><li>number, boolean, string </li></ul></ul></ul><ul><ul><ul><li>Liste: list e variant </li></ul></ul></ul><ul><ul><ul><li>Script </li></ul></ul></ul>
  14. 14. Alcune proprietà fondamentali <ul><li>Ereditate da Item </li></ul><ul><ul><ul><li>scale : real </li></ul></ul></ul><ul><ul><ul><li>rotation : real </li></ul></ul></ul><ul><ul><ul><li>transform : list<Transform> </li></ul></ul></ul><ul><ul><ul><li>visible : bool </li></ul></ul></ul><ul><ul><ul><li>opacity : real </li></ul></ul></ul><ul><ul><ul><li>width, height : real </li></ul></ul></ul><ul><ul><ul><li>x, y, z : real </li></ul></ul></ul><ul><ul><ul><li>parent : Item </li></ul></ul></ul><ul><ul><ul><li>clip : bool </li></ul></ul></ul>
  15. 15. Il property Binding <ul><li>Proprietà associate ad espressioni JavaScript </li></ul><ul><li>Assegnamento QML != Assegnamento JavaScript </li></ul><ul><li>L'elemento Binding </li></ul>Questi sono binding Questi NO! Rectangle { id : root ; width : 360; height : 360 Rectangle { id : redRect width : root.width / 2 height : root.height / 2 } Component.onCompleted : { redRect.width = root.width / 2 redRect.height = root.height / 2 } }
  16. 16. Comporre la User Interface <ul><li>QML offre 3 modi diversi per posizionare elementi nella User Interface: </li></ul><ul><li>Layout basati su anchor </li></ul><ul><ul><ul><li>Dimensioni e posizione relativi ad elementi parent o sibling </li></ul></ul></ul><ul><li>Elementi Positioner </li></ul><ul><ul><ul><li>Elementi speciali che gestiscono posizione e dimensioni degli elementi figli </li></ul></ul></ul><ul><li>Proprietà x, y, width ed height </li></ul><ul><ul><ul><li>Modifica diretta delle proprietà </li></ul></ul></ul>
  17. 17. Layout basati su anchor Rectangle { width : 200; height : 200; color : &quot;red&quot; Rectangle { width : 100; height : 100; color : &quot;blue&quot; anchors.top : parent.top anchors.horizontalCenter : parent.horizontalCenter anchors.topMargin : 10 anchors.horizontalCenterOffset : -20 } } <ul><li>7 linee “ideali”: top, right, bottom left, horizontal center, vertical center, baseline </li></ul><ul><li>Allineamento di un elemento a parent o sibling </li></ul><ul><li>Margini e offset validi solo per le anchor specificate </li></ul><ul><li>anchors.fill e anchors.centerIn </li></ul><ul><li>Distanze in pixel </li></ul>
  18. 18. Elementi Positioner Column { anchors.centerIn : parent Rectangle { width : 100; height : 100; color : &quot;red&quot; } Rectangle { width : 100; height : 100; color : &quot;blue&quot; } Rectangle { width : 100; height : 100; color : &quot;green&quot; } } <ul><li>Gestiscono la posizione degli elementi child </li></ul><ul><li>Column, Row, Grid e Flow </li></ul><ul><li>Discendono direttamente da Item, non da Rectangle </li></ul>
  19. 19. Proprietà x, y, width e height Rectangle { width : 200; height : 200; color : &quot;red&quot; Rectangle { color : &quot;blue&quot; width : 100 height : 100 x : 50 y : 80 } } <ul><li>Posizione (x,y) relativa a parent </li></ul><ul><li>Le anchors, se definite, hanno priorità rispetto a posizione e dimensione specificate esplicitamente </li></ul>
  20. 20. Interazione Utente – Touch <ul><li>MouseArea : elemento non visuale </li></ul><ul><li>Aggiunto ad elementi visuali con anchors.fill = parent </li></ul><ul><li>Interazione signal -based </li></ul><ul><ul><ul><li>onPressed, onReleased, onPressAndHold </li></ul></ul></ul>Rectangle { width : 200; height : 200; color : &quot;red&quot; MouseArea { anchors.fill : parent onPressed : parent.color = &quot;blue&quot; onReleased : parent.color = &quot;red&quot; } }
  21. 21. Interazione Utente – Touch <ul><li>Interazione property -based </li></ul><ul><ul><ul><li>containsMouse, pressed, pressedButtons </li></ul></ul></ul><ul><li>Necessario settare l'id della MouseArea </li></ul><ul><li>Proprietà drag </li></ul>Rectangle { width : 200; height : 200 color : myMouseArea.pressed ? &quot;blue&quot; : &quot;red&quot; MouseArea { id : myMouseArea drag.target : parent anchors.fill : parent } }
  22. 22. Interazione Utente – Tastiera <ul><li>Keys attached property per elementi visuali </li></ul><ul><li>Eventi intercettati da elemento con focus attivo </li></ul><ul><li>Keys.onPressed , Keys.onReleased , … </li></ul><ul><ul><ul><li>Parametro ( KeyEvent event) </li></ul></ul></ul><ul><ul><ul><li>accepted = true per fermare propagazione evento </li></ul></ul></ul>Rectangle { width : 100; height : 100; focus : true; Keys.onPressed : if (event.key == Qt.Key_Left) console.log( &quot;LEFT&quot; ) Keys.onUpPressed : console.log( &quot;UP&quot; ) }
  23. 23. Gestione del focus <ul><li>Proprietà activeFocus permette di controllare se un Item ha focus attivo </li></ul><ul><li>Elemento FocusScope permette di gestire il focus in maniera modulare </li></ul><ul><ul><ul><li>In un FocusScope solo un Item può avere focus=true </li></ul></ul></ul><ul><ul><ul><li>Quando un FocusScope riceve l' activeFocus , lo riceve anche l'elemento con focus=true </li></ul></ul></ul><ul><ul><ul><li>Permette di ricordare l'elemento child che aveva focus </li></ul></ul></ul><ul><li>L'elemento con activeFocus=true riceve gli eventi della tastiera </li></ul>
  24. 24. Estendere QML con nuovi componenti <ul><li>Componente: elemento QML riutilizzabile, scritto in QML </li></ul><ul><li>Codice QML in file “NomeComponente.qml” </li></ul><ul><li>Proprietà, Metodi e Segnali </li></ul><ul><li>Possibile definire componenti inline </li></ul>RoundedTextInput.qml Rectangle { radius : 5 color : &quot;blue&quot; property string text: textInput.text TextInput { id : textInput color : &quot;white&quot; anchors.fill : parent ; anchors.margins : 5 } }
  25. 25. Estendere QML con nuovi componenti <ul><li>Che succede settando il valore della proprietà text? </li></ul><ul><ul><ul><li>Si perde il binding!!! </li></ul></ul></ul><ul><li>La soluzione: i property alias </li></ul><ul><li>Proprietà definita come alias di una seconda proprietà property alias text: textInput.text </li></ul>main.qml Rectangle { width : 300; height : 300 RoundedTextInput { height : 60 width : parent.width text : &quot;Some default text&quot; } }
  26. 26. Property Alias <ul><li>Connessione tra 2 proprietà </li></ul><ul><li>Binding != Alias </li></ul><ul><li>Bidirezionale </li></ul><ul><li>Utili per i componenti </li></ul><ul><li>Inizializzate solo a componente caricato </li></ul>Item { width : 200; height : 200 property alias rectColor: myRect.color rectColor : &quot;blue&quot; // NON FUNZIONA! Rectangle { id : myRect ; anchors.fill : parent } }
  27. 27. Aggiungere segnali ad un componente <ul><li>Definiti con la sintassi: </li></ul><ul><ul><ul><li>signal <name>[(<type> <value>, …)] </li></ul></ul></ul><ul><li>Handler: on<name>: <expression> </li></ul>RoundedButton.qml Rectangle { radius : 5; color : &quot;blue&quot; property string text signal buttonClicked Text { anchors.centerIn : parent text : parent.text color : &quot;white&quot; } MouseArea { anchors.fill : parent onClicked : parent.buttonClicked() } }
  28. 28. Definire metodi per un componente RoundedButton.qml Rectangle { radius : 5; color : &quot;blue&quot; property string text function getSomeValue() { return Math.random() } ... } main.qml RoundedButton { id : myButton width : 450; height : 100 text : &quot;Click me&quot; Component.onCompleted : { console.log( myButton.getSomeValue() ); } }
  29. 29. Componenti e moduli <ul><li>Un modulo rappresenta un insieme di file QML importabili in una applicazione QML </li></ul><ul><li>Importando un folder, tutti i componenti contenuti diventano disponibili </li></ul><ul><ul><ul><li>Sia risorse locali che remote </li></ul></ul></ul>Struttura folder MyApp |- main.qml |- MyModule / |- Triangle.qml |- Circle.qml |- Ellipsis.qml main.qml import QtQuick 1.0 import &quot;MyModule&quot; Rectangle { width : 300; height : 300 Triangle {...} Circle {...} Ellipsis {...} }
  30. 30. Versioning e named imports qmldir metadata file Triangle 1.0 Triangle.qml Circle 1.0 Circle.qml Ellipsis 1.0 Ellipsis.qml main.qml import QtQuick 1.0 import &quot;MyModule&quot; 1.0 Rectangle { width : 300; height : 300 Triangle {...} } <ul><li>File qmldir permette di specificare diverse versioni per ciascun componente </li></ul><ul><li>La keyword 'as' permette di specificare namespace per ciascun import </li></ul>import &quot;MyModule&quot; 1.0 as Shapes Rectangle { width : 300; height : 300 Shapes.Triangle {...} }
  31. 31. Gestire e visualizzare dati <ul><li>DataModel </li></ul><ul><li>Metodi per inserimento/rimozione dinamica di dati </li></ul><ul><li>ListModel : modello di base </li></ul><ul><ul><ul><li>Elementi di tipo ListElement </li></ul></ul></ul><ul><ul><ul><li>Proprietà custom </li></ul></ul></ul>ListModel { id : myModel ListElement { nome : &quot;Symbian&quot; } ListElement { nome : &quot;Maemo&quot; } ListElement { nome : &quot;MeeGo&quot; } }
  32. 32. Visualizzazione di un Data Model ListModel { id : myModel ListElement { colore : &quot;blue&quot; } ListElement { colore : &quot;red&quot; } ListElement { colore : &quot;green&quot; } } Row { anchors.centerIn : parent spacing : 20 Repeater { model : myModel delegate : Rectangle { width : 200; height : 200 color : colore Text { text : index; anchors.centerIn : parent} } } } <ul><li>Proprietà del model accessibili direttamente </li></ul><ul><li>Proprietà index </li></ul><ul><li>Repeater utile con modelli semplici </li></ul>
  33. 33. Visualizzazione efficiente: le Views ListModel { id : myModel ListElement { nome : &quot;Symbian&quot; } ListElement { nome : &quot;Maemo&quot; } ListElement { nome : &quot;MeeGo&quot; } } ListView { anchors.fill : parent model : myModel focus : true delegate : Rectangle { color : ListView.isCurrentItem ? &quot;lightblue&quot; : &quot;white&quot; width : parent.width; height : 100 border { width : 1; color : &quot;black&quot; } Text { text : nome; anchors.centerIn : parent} } } <ul><li>Visualizzazione efficiente </li></ul><ul><li>Supporto per: scrolling, header/footer, highlight </li></ul><ul><li>GridView : visualizzazione in griglia </li></ul>
  34. 34. Altri Data Model... VisualItemModel { id : myModel Rectangle { width : 800; height : 100; color : &quot;red&quot; } Rectangle { width : 800; height : 100; color : &quot;blue&quot; } Rectangle { width : 800; height : 100; color : &quot;green&quot; } } ListView { anchors.fill : parent; model : myModel } VisualItemModel ListView { anchors.fill : parent model : 100 delegate : Text { text : &quot;Index: &quot; + index } } Anche un Number! <ul><li>Definisce direttamente gli elementi da visualizzare </li></ul><ul><ul><ul><li>Proprietà delegate non specificata </li></ul></ul></ul>
  35. 35. Animare la User Interface <ul><li>Variazione progressiva delle proprietà di un elemento </li></ul><ul><li>Classe di base: Animation </li></ul><ul><ul><ul><li>NumberAnimation, ColorAnimation, RotationAnimation </li></ul></ul></ul><ul><li>Animazioni parallele e sequenziali </li></ul><ul><li>Controllo su playback animazione </li></ul><ul><ul><ul><li>Metodi play, pause, stop, resume, restart, complete </li></ul></ul></ul><ul><li>Elementi speciali: PauseAnimation, PropertyAction, ScriptAction </li></ul><ul><li>Easing curves </li></ul><ul><ul><ul><li>Proprietà easing.type </li></ul></ul></ul>
  36. 36. Animazione esplicita Item { width : 360; height : 360 Image { width : 64; height : 64 source : &quot;myImage.png&quot; NumberAnimation on x { from : 0; to : 200 duration : 3000 easing.type : Easing.OutElastic } } } <ul><li>NumberAnimation : animazioni per proprietà numeriche </li></ul><ul><li>L'animazione inizia subito </li></ul><ul><li>Proprietà duration espressa in millisecondi </li></ul><ul><li>from e to settati esplicitamente </li></ul>
  37. 37. Animazione standalone Item { width : 360; height : 360 Image { id : myImage; width : 64; height : 64; source : &quot;myImage.png&quot; MouseArea { anchors.fill : parent onClicked : myAnimation.running = true } } NumberAnimation { id : myAnimation target : myImage ; properties : &quot;x&quot; from : 0; to : 200; duration : 3000 } } <ul><li>NumberAnimation definita fuori dall'elemento target </li></ul><ul><li>Proprietà definite come stringa </li></ul><ul><li>running false di default </li></ul>
  38. 38. Animazione al variare di una proprietà Item { width : 360; height : 360 Image { id : myImage width : 64; height : 64 ; source : &quot;myImage.png&quot; Behavior on x { NumberAnimation { duration : 3000 } } } Component.onCompleted : { myImage.x = 200 } } <ul><li>Elemento Bevahior </li></ul><ul><li>target , from e to definiti implicitamente </li></ul>
  39. 39. Animazione in un signal handler Item { width : 360; height : 360 Image { id : myImage width : 64; height : 64 ; source : &quot;myImage.png&quot; MouseArea { anchors.fill : parent onClicked : NumberAnimation { target : myImage; properties : &quot;x&quot; to : 200; duration : 3000 } } } } <ul><li>Proprietà target e properties settate esplicitamente </li></ul>
  40. 40. Gestire la UI tramite stati <ul><li>Rappresentati dall'elemento State </li></ul><ul><li>Definiscono stati diversi della UI </li></ul><ul><li>Proprietà state e states </li></ul><ul><li>Stato di default </li></ul><ul><li>Set di cambiamenti applicati ai vari elementi e proprietà </li></ul><ul><li>Uno stato può: </li></ul><ul><ul><ul><li>Aggiornare il valore di una proprietà </li></ul></ul></ul><ul><ul><ul><li>Eseguire script </li></ul></ul></ul><ul><ul><ul><li>Settare nuovi signal handler </li></ul></ul></ul><ul><ul><ul><li>Cambiare il parent di un elemento </li></ul></ul></ul><ul><ul><ul><li>Modificare il valore delle anchor </li></ul></ul></ul>
  41. 41. Definizione di uno stato Rectangle { id : root ; width : 360; height : 360 ; color : &quot;red&quot; states : [ State { name : &quot;pressed&quot; PropertyChanges { target : root color : &quot;blue&quot; } } ] } <ul><li>La proprietà states definisce l'elenco dei possibili stati </li></ul><ul><li>Uno State è identificato dalla proprietà name </li></ul><ul><li>Gli elementi PropertyChanges definiscono il set di cambiamenti </li></ul>
  42. 42. Attivazione di uno stato Rectangle { id : root ; width : 360; height : 360 ; color : &quot;red&quot; states : […] MouseArea { anchors.fill : parent onPressed : root.state = &quot;pressed&quot; onReleased : root.state = &quot;&quot; } } <ul><li>La proprietà state definisce lo stato attuale di un elemento </li></ul><ul><li>Lo stato di default è dato da “” </li></ul>
  43. 43. Condizioni di uno stato Rectangle { id : root ; width : 360; height : 360 ; color : &quot;red&quot; states : [ State { when : myMouseArea.pressed name : &quot;pressed&quot; PropertyChanges {...} } ] MouseArea { id : myMouseArea anchors.fill : parent } } <ul><li>La proprietà booleana when definisce quando uno stato deve essere attivato </li></ul><ul><li>Proprietà state aggiornata automaticamente </li></ul>
  44. 44. Transizioni tra stati Rectangle { [...] transitions : [ Transition { from : &quot;&quot; to : &quot;pressed&quot; PropertyAnimation { target : root; properties : &quot;color&quot; ; duration : 250 } } ] } <ul><li>Le proprietà from e to definiscono gli stati di interesse </li></ul><ul><ul><ul><li>Si possono omettere oppure usare “*” </li></ul></ul></ul><ul><li>Una o più Animation definiscono le proprietà da animare </li></ul>
  45. 45. Animazioni parallele e sequenziali Image { id : myImage width : 64; height : 64; source : &quot;qt-logo.png&quot; SequentialAnimation { running : true; NumberAnimation { target : myImage; properties : &quot;x&quot; from : 0; to : 200; duration : 1000 } ParallelAnimation { NumberAnimation { target : myImage; properties : &quot;rotation&quot; from : 0; to : 90; duration : 1000 } NumberAnimation { target : myImage; properties : &quot;y&quot; from : 0; to : 200; duration : 1000 } } } }
  46. 46. QML e JavaScript <ul><li>Inline e librerie esterne </li></ul><ul><li>Named Imports: import &quot;js/MyLibrary.js&quot; as CoreLogic </li></ul><ul><ul><ul><li>Chiamate JS: CoreLogic.myFunction() </li></ul></ul></ul><ul><li>Librerie stateful e stateless </li></ul><ul><ul><ul><li>.pragma library </li></ul></ul></ul><ul><li>Global object non modificabile </li></ul><ul><li>Qt.include() </li></ul><ul><li>XMLHttpRequest (NO modalità sincrona) </li></ul><ul><li>Component.onCompleted </li></ul><ul><li>Non è JavaScript che troviamo sul Web! </li></ul><ul><ul><ul><li>Ad es.: no setInterval/setTimeout , vanno invece usati elementi Timer </li></ul></ul></ul>
  47. 47. Esempio di libreria JavaScript function startup() { // cambio il colore dell'elemento con id “root” root.color = &quot;lightblue&quot; ; } function randomNumber() { return Math.random(); } js/MyLibrary.js import &quot;js/MyLibrary.js&quot; as CoreLogic Rectangle { id : root; width : 200; height : 200 Text { text : &quot;Numero casuale: &quot; + CoreLogic.randomNumber(); } Component.onCompleted : CoreLogic.startup(); } main.qml
  48. 48. Estendere QML in C++ <ul><li>Implementare nuovi Data Model </li></ul><ul><li>Accesso a funzionalità Qt </li></ul><ul><li>Creare nuovi elementi visuali o non visuali </li></ul><ul><ul><ul><li>Non tutto si può fare con i componenti QML </li></ul></ul></ul><ul><li>Elementi visuali estendono QdeclarativeItem </li></ul><ul><li>Elementi non visuali estendono Qobject </li></ul><ul><li>Si possono definire proprietà, metodi, segnali </li></ul><ul><li>Nuovi elementi vanno: </li></ul><ul><ul><ul><li>Implementati e registrati lato C++ </li></ul></ul></ul><ul><ul><ul><li>Importati (ed usati) lato QML </li></ul></ul></ul>
  49. 49. Utilizzo di un tipo implementato in C++ import QtQuick 1.0 import FormeGeometriche 1.0 Rectangle { width : 300 height : 300 Triangolo { anchors.centerIn : parent width : 200 height : 100 color : &quot;green&quot; } } <ul><li>Va importato il modulo corrispondente </li></ul><ul><ul><ul><li>Modulo definito con la registrazione del tipo lato C++ </li></ul></ul></ul><ul><li>Si può utilizzare come qualsiasi altro tipo QML </li></ul>
  50. 50. Implementiamo il nuovo visual item triangleitem.h #include <QDeclarativeItem> class Triangletem : public QDeclarativeItem { Q_OBJECT public : explicit Triangletem ( QDeclarativeItem *parent = 0 ); void paint ( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 ); }; <ul><li>Si importa e subclassa QDeclarativeItem </li></ul><ul><ul><ul><li>Elementi non visuali subclassano QObject </li></ul></ul></ul><ul><li>Unico metedo necessario: paint() </li></ul>
  51. 51. Definire nuove proprietà triangleitem .h class TriangleItem : public QDeclarativeItem { Q_OBJECT Q_PROPERTY ( QColor color READ color WRITE setColor NOTIFY colorChanged) public : [...] const QColor &color() const ; void setColor ( const QColor & newColor ); signals : void colorChanged(); private : QColor m_color ; }; <ul><li>Macro Q_PROPERTY </li></ul><ul><li>Funzioni setter e getter </li></ul><ul><li>Signal emesso quando cambia il valore della proprietà </li></ul>
  52. 52. Costruttore e metodo paint() triangleitem.cpp TriangleItem :: TriangleItem ( QDeclarativeItem *parent) : QDeclarativeItem (parent) { setFlag( QGraphicsItem :: ItemHasNoContents , false); } void TriangleItem :: paint ( QPainter *painter, const QstyleOptionGraphicsItem *option, QWidget *widget) { painter->save(); painter->setBrush( m_color ); QPolygon triangolo; triangolo.putPoints( 0 , 3 , option-> rect .width()/ 2 , 0 , 0 , option-> rect .height(), option-> rect .width(), option-> rect .height()); painter->drawPolygon(triangolo); painter->restore(); } <ul><li>Flag QGraphicsItem::ItemHasNoContents = false </li></ul><ul><li>save() e restore() ripristinano lo stato del painter </li></ul><ul><li>La property viene usata per settare il colore dell'ellisse </li></ul>
  53. 53. Implementiamo setter e getter triangleitem.cpp const QColor & TriangleItem :: color () const { return m_color ; } void TriangleItem ::setColor(const QColor &newColor) { if ( m_color != newColor) { m_color = newColor; update (); emit colorChanged (); } } <ul><li>Getter immediato </li></ul><ul><li>Setter: </li></ul><ul><ul><ul><li>Controllo che il nuovo valore sia diverso </li></ul></ul></ul><ul><ul><ul><li>Repaint </li></ul></ul></ul><ul><ul><ul><li>Emissione segnale colorChanged </li></ul></ul></ul>
  54. 54. Registrazione del nuovo tipo main.cpp int main (int argc, char *argv[]) { QApplication app(argc, argv); qmlRegisterType< TriangleItem >( &quot;FormeGeometriche&quot; , 1 , 0 , &quot;Triangolo&quot; ); QmlApplicationViewer viewer; viewer.setOrientation( QmlApplicationViewer :: ScreenOrientationAuto ); viewer.setMainQmlFile( QLatin1String ( &quot;qml/MyQtQuickApp/main.qml&quot; )); viewer.showExpanded(); return app.exec(); } <ul><li>qmlRegisterType permette di impostare: </li></ul><ul><ul><ul><li>Nome del modulo </li></ul></ul></ul><ul><ul><ul><li>Numero di versione major e minor </li></ul></ul></ul><ul><ul><ul><li>Nome del nuovo elemento </li></ul></ul></ul>
  55. 55. Aggiungere metodi richiamabili da QML triangleitem.h class TriangleItem : public QDeclarativeItem { public : Q_INVOKABLE QColor randomColor() const; } triangleitem.cpp QColor TriangleItem :: randomColor () const { return QColor (qrand() & 0xff , qrand() & 0xff , qrand() & 0xff ); } main.qml Triangolo { width : 200; height : 100 color : randomColor() } <ul><li>Macro Q_INVOKABLE </li></ul><ul><li>Metodi che non ritornano valori dichiarabili come slot Qt </li></ul>
  56. 56. Aggiungere proprietà custom triangleitem.h class TriangleItem : public QDeclarativeItem { Q_ENUMS ( Style ) public: enum Style { Normal , UpsideDown }; const Style &style() const; void setStyle(const Style &newStyle); private : Style m_style ; } <ul><li>Proprietà possono essere: </li></ul><ul><ul><ul><li>enums </li></ul></ul></ul><ul><ul><ul><li>Altri elementi (dichiarati e registrati come visto) </li></ul></ul></ul><ul><ul><ul><li>Liste di altri elementi </li></ul></ul></ul><ul><li>Definizione di una proprietà enum: </li></ul>
  57. 57. Utilizzo di proprietà enum triangleitem.cpp void TriangleItem :: paint ( QPainter *painter, const QstyleOptionGraphicsItem *option, QWidget *widget) { painter->save(); painter->setBrush( m_color ); QPolygon triangolo; if ( m_style == UpsideDown ) triangolo.putPoints( 0 , 3 , option-> rect .width()/ 2 , option-> rect .height(), 0 , 0 , option-> rect .width(), 0 ); else triangolo.putPoints( 0 , 3 , option-> rect .width()/ 2 , 0 , 0 , option-> rect .height(), option-> rect .width(), option-> rect .height()); painter->drawPolygon(triangolo); painter->restore(); } triangleitem.cpp Triangolo { anchors.centerIn : parent width : 200; height : 100 color : randomColor() style : Triangolo.UpsideDown }
  58. 58. Velocizziamo lo sviluppo <ul><li>Export automatico da Photoshop e GIMP a QML </li></ul><ul><li>Qt Quick Components: set di componenti e modelli Qt/QML: http://qt.gitorious.org/qt-components/ </li></ul>v
  59. 59. Plugin QML di Qt Mobility <ul><li>Offrono accesso ad API Qt con sintassi dichiarativa: </li></ul><ul><ul><ul><li>Contacts </li></ul></ul></ul><ul><ul><ul><li>Feedback </li></ul></ul></ul><ul><ul><ul><li>Gallery : accesso a documenti della Document Gallery </li></ul></ul></ul><ul><ul><ul><li>Location : mappe e coordinate </li></ul></ul></ul><ul><ul><ul><li>Multimedia : playback audio/video, accesso a fotocamera </li></ul></ul></ul><ul><ul><ul><li>Organizer : accesso a dati calendario, ToDo, ... </li></ul></ul></ul><ul><ul><ul><li>Publish and Subscribe </li></ul></ul></ul><ul><ul><ul><li>Service Framework </li></ul></ul></ul><ul><ul><ul><li>Messaging : accesso a messaggi </li></ul></ul></ul><ul><ul><ul><li>System Information : network, lingua, ... </li></ul></ul></ul><ul><ul><ul><li>Sensors : accelerometro, compass, prossimità ... </li></ul></ul></ul>
  60. 60. Grazie!

×