25. listopadu 2014, Brno Připravil: David Procházka QML (2) Programovací jazyk C++
Obsah přednášky Strana 2 / 32 Obsah přednášky 1 Obsah přednášky 2 Volání C++ kódu 3 Dialogy 4 XML soubory 5 Drag & drop 6 Závěr
Obsah přednášky Strana 3 / 32 Obsah přednášky Dnes se naučíme vytvořit grafické uživatelské rozhraní pomocí knihovny Qt a jazyka QML.
Volání C++ kódu Strana 4 / 32 Obsah přednášky 1 Obsah přednášky 2 Volání C++ kódu 3 Dialogy 4 XML soubory 5 Drag & drop 6 Závěr
Volání C++ kódu Strana 5 / 32 Vytvoření C++ třídy volatelné z QML Třída musí být potomkem QObject. Volatelná metoda musí být označena makrem Q INVOCABLE. 1 class TileGenerator : public QObject 2 { 3 Q_ OBJECT 4 public : 5 Q_ INVOKABLE int gettilecontent ( QString index ); 6 Q_ INVOKABLE void saveresults ( QString result ); 7...
Volání C++ kódu Strana 6 / 32 Zaregistrování instance třídy pro QML Musíte vytvořit instanci této třídy main. Přiřadíte jí jméno pro QML a zaregistrujete. 1 int main ( int argc, char * argv []){ 2 QApplication app ( argc, argv ); 3 4 QQmlApplicationEngine engine ; 5 engine. load ( QUrl ( QStringLiteral (" qrc :/// main. qml " ))) 6 7 TileGenerator gen ; 8 QQmlContext * context = engine. rootcontext (); 9 context -> setcontextproperty (" generator ", & gen ); 10 11 return app. exec (); 12 }
Volání C++ kódu Strana 7 / 32 Volání v QML V QML kódu se pak volá přes název použitý při registraci. Volá se metoda stále stejné instance. 1 MouseArea { 2 anchors. fill : parent 3 4 onclicked : { 5 generator. saveresults ( data ) 6 Qt. quit () 7 } 8 }
Dialogy Strana 8 / 32 Obsah přednášky 1 Obsah přednášky 2 Volání C++ kódu 3 Dialogy 4 XML soubory 5 Drag & drop 6 Závěr
Dialogy Strana 9 / 32 Dialogy Dialog, stejně jako další prvky GUI lze vytvářet jako pomocí klasických widgetů, tak pomocí QML kódu označováno Qt Quick. (Pozor při hledání nápovědy.) Dialogů je celá řada: ColorDialog výběr bavy, FileDialog výběr souboru nebo adresáře, FontDialog výběr fontu, MessageDialog obecná popup zpráva.
Dialogy Strana 10 / 32 Výběr bavy 1 ColorDialog { 2 id: colordialog 3 visible : true 4 modality : Qt. WindowModal // Qt. NonModal 5 title : " Choose a color " 6 color : " green " 7 showalphachannel : true 8 onaccepted : { 9 console. log (" Accepted : " + color ) 10 } 11 onrejected : { 12 console. log (" Rejected ") 13 } 14 }
Dialogy Strana 11 / 32 Výběr souboru 1 FileDialog { 2... 3 selectexisting : true // vyber exist. souboru / slozky? 4 selectmultiple : true // vyb. vice souboru / slozek? 5 selectfolder : true // lze vybrat slozku? 6 namefilters : [" Images (*. png *. jpg )"," All (*) "] 7 selectednamefilter : " All files (*) " 8 onaccepted : { 9 console. log (" Accepted : " + fileurls ) 10 for ( var i = 0; i < fileurls. length ; ++ i) 11... 12 } 13 onrejected : { 14 console. log (" Rejected ") 15 } 16 }
Dialogy Strana 12 / 32 Obecný dialog Obecný dialog může mít řadu formátů. Můžeme mu definovat standardní ikonky (vlstnost icon): StandardIcon.Question StandardIcon.Information StandardIcon.Warning StandardIcon.Critical Můžeme mu také definovat standardní tlačítka. Každé tlačítko má nějakou roli, na kterou se reaguje: AcceptRole (potvrzení), RejectRole (rušení) atp. Např. 1 StandardButton.Ok (AcceptRole) StandardButton.Save (AcceptRole) StandardButton.Cancel (RejectRole) StandardButton.Close (RejectRole) 1 http: //qt-project.org/doc/qt-5/qml-qtquick-dialogs-messagedialog.html
Dialogy Strana 13 / 32 Obecný dialog 1 import QtQuick 2.2 2 import QtQuick. Dialogs 1.1 3 4 MessageDialog { 5 id: messagedialog 6 title : " Chcete hru opravdu vypnout?" 7 text : " Meli byste si to rozmyslet " 8 onaccepted : { 9 console. log ("On to fakt vypnul.") 10 Qt. quit () 11 } 12 Component. oncompleted : visible = true 13 }
Dialogy Strana 14 / 32 Obecný dialog 1 MessageDialog { 2 title : " Overwrite?" 3 icon : StandardIcon. Question 4 text : " file. txt already exists. Replace?" 5 detailedtext : " To replace a file... " 6 standardbuttons : StandardButton. Yes 7 StandardButton. YesToAll 8 StandardButton. No 9 StandardButton. NoToAll 10 StandardButton. Abort 11 Component. oncompleted : visible = true 12 onyes : console. log (" copied ") 13 onno : console. log (" didn t copy ") 14 onrejected : console. log (" aborted ") 15 }
XML soubory Strana 15 / 32 Obsah přednášky 1 Obsah přednášky 2 Volání C++ kódu 3 Dialogy 4 XML soubory 5 Drag & drop 6 Závěr
XML soubory Strana 16 / 32 XML soubory XML soubory představují hierarchickou reprezentaci dat. Jsou jednou z možností standandardizovaného zápisu dat (JSON). 1 <? xml version =" 1.0 " encoding ="utf -8"?> 2 <rss version =" 2.0 "> 3... 4 <channel > 5 <item > 6 <title >A blog post </ title > 7 <pubdate >Sat, 07 Sep 2010... </ pubdate > 8 </item > 9 <item > 10 < title > Another blog post </ title > 11 <pubdate >Sat, 07 Sep 2010... </ pubdate > 12 </item > 13...
XML soubory Strana 17 / 32 Parsery Existuje několik způsobů zpracování XML souborů. Používají se na to tzv. parsery. Existují 2 základní přístupy: SAX a DOM. DOM (Document Object Model) načte se celý soubor a vytvoří objektový model (elegantní, ale náročné). SAX (http://www.saxproject.org) soubor se načítá po částech (méně elegantní, ale rychlé). Struktura dokumentu může být popsána pomocí DTD (starší, SGML formát) nebo XML Schema (XML syntaxe) dokumentu. Před procházením lze dokument validovat. Nad XML lze klást dotazy pomocí: XPath nalezení určitého elementu souboru, XPointer totéž + jednodušší rozhraní, XQuery SQL-like syntaxe. V QT jsou oddělené parsery pro C++ a pro QML.
XML soubory Strana 18 / 32 SAX-like parser Je založený na zpracování událostí (načten element). Každý načtený element je analyzován a je nastaveno rozhodnutí, co se má udělat. Typicky definujeme reakce na situace, že načten: otevírací element (analyzujeme jeho jméno, parametry), uzavírací element (neděláme nic, nebo ukončíme načítání skupiny dat). V QT je implementován prostřednictvím tříd QXmlStreamReader a QXmlStreamWriter. Existuje také zjednodušená nevalidující verze parseru QXmlSimpleReader, QXmlSimpleWriter.
XML soubory Strana 19 / 32 Základní princip čtení 1 QFile file ( filename ); 2 if( file. open ( QIODevice :: ReadOnly )) { 3 QXmlStreamReader xmlreader ; 4 xmlreader. setdevice (& file ); 5 /// Nactu prvni token 6 xmlreader. readnext (); 7 8 /// Cti dokud neni konec dokumentu 9 while (! xmlreader. isenddocument ()){ 10 /// Je to pocatecni token? 11 if ( xmlreader. isstartelement ()){ 12 /// Nacti jeho jmeno 13 QString name = xmlreader. name (). tostring (); 14 if ( name == " square "){ 15 area = xmlreader. readelementtext (). toint (); 16 id = xmlreader. attributes (). value ("id"). toint ( 17...
XML soubory Strana 20 / 32 Základní princip zápisu 1 QFile file ( filename. split ("//"). at (1)); 2 if( file. open ( QIODevice :: WriteOnly )){ 3 QXmlStreamWriter writer ; 4 writer. setdevice (& file ); 5 6 writer. writestartdocument (); 7 writer. writestartelement (" results "); 8 9 writer. writestartelement (" result "); 10 writer. writeattribute (" game ","0"); 11 writer. writecharacters ( text ); 12 writer. writeendelement (); 13 14 writer. writeendelement (); 15 writer. writeenddocument (); 16...
XML soubory Strana 21 / 32 Příklad XPath dotazu v QML příklad Mějme RSS soubor s novinkami. 1 <? xml version =" 1.0 " encoding ="utf -8"?> 2 <rss version =" 2.0 "> 3... 4 <channel > 5 <item > 6 <title >A blog post </ title > 7 <pubdate >Sat, 07 Sep 2010 10:00:01 GMT </ pubdate > 8 </item > 9 <item > 10 < title > Another blog post </ title > 11 <pubdate >Sat, 07 Sep 2010 15:35:01 GMT </ pubdate > 12 </item > 13 </ channel > 14 </rss >
XML soubory Strana 22 / 32 Příklad XPath dotazu v QML dotaz Ze souboru chceme vytáhnout seznam novinek a zobrazit jej jako textová pole. Nadefinujeme dotaz extrahující potřebné elementy. 1 import QtQuick 2.0 2 import QtQuick. XmlListModel 2.0 3 4 XmlListModel { 5 id: xmlmodel 6 source : " http :// www. mysite. com / feed. xml " 7 query : "/ rss / channel / item " 8 9 XmlRole { name : " title "; query : " title / string ()" } 10 XmlRole { name : " pubdate "; query :" pubdate / string ()"} 11 }
XML soubory Strana 23 / 32 Příklad XPath dotazu v QML zobrazení Nyní můžu převzít výsledky, které XmlListModel vygeneruje a zobrazit je pomocí repeateru, listview atp. 1 ListView { 2 width : 180; height : 300 3 model : xmlmodel 4 delegate : Text { text : title + ": " + pubdate } 5 }
Drag & drop Strana 24 / 32 Obsah přednášky 1 Obsah přednášky 2 Volání C++ kódu 3 Dialogy 4 XML soubory 5 Drag & drop 6 Závěr
Drag & drop Strana 25 / 32 Drag & drop umožňuje měnit polohu elementů. Dlouhou dobu se v Qt používá pro přidání položek do widgetů se seznamy atp. V QML jej lze aktivovat pro celé elementy. U každého elementu, který lze přesouvat musíme definovat: zdrojový element, ve kterém se přetahovaný objekt bude nacházet napočátku, cílový element, do kterého je povoleno provést přesun. Pro identifikaci povolené kombinace přesunovaného objektu a cíle slouží klíč.
Drag & drop Strana 26 / 32 Drag & drop Drag & drop umožňuje měnit polohu elementů. Dlouhou dobu se v Qt používá pro přidání položek do widgetů se seznamy atp. V QML jej lze aktivovat pro celé elementy. U každého elementu, který lze přesouvat musíme definovat: zdrojový element, ve kterém se přetahovaný objekt bude nacházet napočátku, cílový element, do kterého je povoleno provést přesun. Pro identifikaci povolené kombinace přesunovaného objektu a cíle slouží klíč.
Drag & drop Strana 27 / 32 Drag & drop zdroj a přesouvaný objekt 1 Item { 2 id: root 3 property string colorkey 4... 5 MouseArea { 6 id: mousearea 7... 8 // kam lze pretahovat 9 drag. target : tile 10 // kam se ma element umistit pokud to nevyjde 11 onreleased : parent = tile. Drag. target!== null? 12 tile. Drag. target : root 13 14 Rectangle { 15...
Drag & drop Strana 28 / 32 Drag & drop přesouvaný objekt 1 Rectangle { 2 id: tile 3 width : 64; height : 64 4 5 // identifikacni klic pro d& d 6 // colorkey byla definovana vyse 7 Drag. keys : [ colorkey ] 8 // jaka cast objektu je aktivni pro d& d 9 Drag. active : mousearea. drag. active 10 // kde se ma objekt zachytit 11 Drag. hotspot.x: 32 12 Drag. hotspot.y: 32 13...
Drag & drop Strana 29 / 32 Drag & drop cíl 1 DropArea { 2 id: dragtarget 3 property string colorkey 4 keys : [ colorkey ] 5 6 Rectangle { 7 id: droprectangle 8 anchors. fill : parent 9 color : colorkey 10 states : [ 11 State { 12 when : dragtarget. containsdrag 13 PropertyChanges { 14 target : droprectangle 15 color : " grey " 16 } 17 }
Drag & drop Strana 30 / 32 Drag & drop použití 1 // cilova pozice kompatibilibni s pretahovanym 2 // objektem - ma stejny klic 3 DropTile { 4 colorkey : " red " 5 x : parent. width - width 6 } 7 // cilova pozice nekompatibilibni s pretahovanym 8 // objektem - ma jiny klic 9 DropTile { 10 colorkey : " blue " 11 x : parent. width - width 12 y : parent. height - height 13 } 14 15 // pretahovany objekt 16 DragTile { colorkey : " red " }
Závěr Strana 31 / 32 Obsah přednášky 1 Obsah přednášky 2 Volání C++ kódu 3 Dialogy 4 XML soubory 5 Drag & drop 6 Závěr
Závěr Strana 32 / 32 Shrnutí Dnes jsme si prošli několik témat důležitých pro vytváření pokročilých QML aplikací: volání C++ kódu z QML, tvorbu dialogů (nejen pro výběr souborů), práci s QML soubory, drag & drop technologii.