25. listopadu 2014, Brno ´ Pˇripravil: David Prochazka
QML (2) Programovac´ı jazyk C++
ˇ Obsah pˇredna´ sky
ˇ Obsah pˇredna´ sky 1
´ sky Obsah pˇrednaˇ
2
´ ı C++ kodu ´ Volan´
3
Dialogy
4
XML soubory
5
Drag & drop
6
´ er ˇ Zav
Strana 2 / 32
ˇ Obsah pˇredna´ sky
Strana 3 / 32
ˇ Obsah pˇredna´ sky Dnes se nauˇc´ıme vytvoˇrit graficke´ uˇzivatelske´ rozhran´ı pomoc´ı knihovny Qt a jazyka QML.
´ ı C++ kodu ´ Volan´
ˇ Obsah pˇredna´ sky 1
´ sky Obsah pˇrednaˇ
2
´ ı C++ kodu ´ Volan´
3
Dialogy
4
XML soubory
5
Drag & drop
6
´ er ˇ Zav
Strana 4 / 32
´ ı C++ kodu ´ Volan´
Strana 5 / 32
Vytvoˇren´ı C++ tˇr´ıdy volatelne´ z QML Tˇr´ıda mus´ı b´yt potomkem QObject. Volatelna´ metoda mus´ı b´yt oznaˇcena makrem Q INVOCABLE. 1 2 3 4 5 6 7
class TileGenerator : public QObject { Q_OBJECT public : Q_INVOKABLE int getTileContent ( QString index ); Q_INVOKABLE void saveResults ( QString result ); ...
´ ı C++ kodu ´ Volan´
Strana 6 / 32
´ ı instance tˇr´ıdy pro QML Zaregistrovan´ ´ tˇr´ıdy main. Mus´ıte vytvoˇrit instanci teto ´ Pˇriˇrad´ıte j´ı jmeno pro QML a zaregistrujete. 1 2
int main ( int argc , char * argv []){ QApplication app ( argc , argv );
3
QQm l A p p l i c a t i o n E n g i n e engine ; engine . load ( QUrl ( QStringLiteral ( " qrc :/// main . qml " )))
4 5 6
TileGenerator gen ; QQmlContext * context = engine . rootContext (); context - > se tC on te xt Pr ope rt y ( " generator " , & gen );
7 8 9 10
return app . exec ();
11 12
}
´ ı C++ kodu ´ Volan´
Strana 7 / 32
´ ı v QML Volan´ ´ ´ V QML kodu se pak vola´ pˇres nazev pouˇzit´y pˇri registraci. ´ stejne´ instance. Vola´ se metoda stale 1 2
MouseArea { anchors . fill : parent
3
onClicked : { generator . saveResults ( data ) Qt . quit () }
4 5 6 7 8
}
Dialogy
ˇ Obsah pˇredna´ sky 1
´ sky Obsah pˇrednaˇ
2
´ ı C++ kodu ´ Volan´
3
Dialogy
4
XML soubory
5
Drag & drop
6
´ er ˇ Zav
Strana 8 / 32
Dialogy
Strana 9 / 32
Dialogy ´ ret jako Dialog, stejneˇ jako dalˇs´ı prvky GUI lze vytvaˇ ´ pomoc´ı klasick´ych widgetu, – ˚ tak pomoc´ı QML kodu ´ ´ ı napov ´ ˇ oznaˇcovano Qt Quick. (Pozor pˇri hledan´ edy.) Dialogu˚ je cela´ ˇrada: ˇ bavy, ColorDialog – v´yber ˇ souboru nebo adresaˇ ´ re, FileDialog – v´yber ˇ fontu, FontDialog – v´yber ´ MessageDialog – obecna´ popup zprava.
Dialogy
ˇ bavy Vyb ´ er 1 2 3 4 5 6 7 8 9 10 11 12 13 14
ColorDialog { id : colorDialog visible : true modality : Qt . WindowModal // Qt . NonModal title : " Choose a color " color : " green " showAlphaChannel : true onAccepted : { console . log ( " Accepted : " + color ) } onRejected : { console . log ( " Rejected " ) } }
Strana 10 / 32
Dialogy
Strana 11 / 32
ˇ souboru Vyb ´ er 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
FileDialog { ... selectExisting : true // vyber exist . souboru / slozky ? selectMultiple : true // vyb . vice souboru / slozek ? selectFolder : true // lze vybrat slozku ? nameFilters : [ " Images (*. png *. jpg ) " ," All (*) " ] sele ct ed Na me Filt er : " All files (*) " onAccepted : { console . log ( " Accepted : " + fileUrls ) for ( var i = 0; i < fileUrls . length ; ++ i ) ... } onRejected : { console . log ( " Rejected " ) } }
Dialogy
Strana 12 / 32
Obecny´ dialog ´ u. Obecn´y dialog muˇ ˚ ze m´ıt ˇradu format ˚ Muˇ ˚ zeme mu definovat standardn´ı ikonky (vlstnost icon): StandardIcon.Question StandardIcon.Information StandardIcon.Warning StandardIcon.Critical
Muˇ ˚ zeme mu take´ definovat standardn´ı tlaˇc´ıtka. ˇ Kaˇzde´ tlaˇc´ıtko ma´ nejakou roli, na kterou se reaguje: AcceptRole (potvrzen´ı), RejectRole (ruˇsen´ı) atp. Napˇr.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
Obecny´ dialog 1 2
import QtQuick 2.2 import QtQuick . Dialogs 1.1
3 4 5 6 7 8 9 10 11 12 13
MessageDialog { id : messageDialog title : " Chcete hru opravdu vypnout ? " text : " Meli byste si to rozmyslet " onAccepted : { console . log ( " On to fakt vypnul . " ) Qt . quit () } Component . onCompleted : visible = true }
Strana 13 / 32
Dialogy
Strana 14 / 32
Obecny´ dialog 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
MessageDialog { title : " Overwrite ? " icon : StandardIcon . Question text : " file . txt already exists . Replace ? " detailedText : " To replace a file ... " standardButtons : StandardButton . Yes | StandardButton . YesToAll | StandardButton . No | StandardButton . NoToAll | StandardButton . Abort Component . onCompleted : visible = true onYes : console . log ( " copied " ) onNo : console . log ( " didn ’t copy " ) onRejected : console . log ( " aborted " ) }
XML soubory
ˇ Obsah pˇredna´ sky 1
´ sky Obsah pˇrednaˇ
2
´ ı C++ kodu ´ Volan´
3
Dialogy
4
XML soubory
5
Drag & drop
6
´ er ˇ Zav
Strana 15 / 32
XML soubory
Strana 16 / 32
XML soubory XML soubory pˇredstavuj´ı hierarchickou reprezentaci dat. ´ ´ Jsou jednou z moˇznost´ı standandardizovaneho zapisu dat (JSON). 1 2 3 4 5 6 7 8 9 10 11 12 13
xml version = " 1.0 " encoding = " utf -8 " ? > < rss version = " 2.0 " > ... < channel > < item > < title > A blog post title > < pubDate > Sat , 07 Sep 2010... pubDate > item > < item > < title > Another blog post title > < pubDate > Sat , 07 Sep 2010... pubDate > item > ...
XML soubory
Strana 17 / 32
Parsery ˇ ´ ı XML souboru. Existuje nekolik zpusob u˚ zpracovan´ ˚ ˚ Pouˇz´ıvaj´ı se na to tzv. parsery. ´ Existuj´ı 2 zakladn´ ı pˇr´ıstupy: SAX a DOM. DOM (Document Object Model) – naˇcte se cel´y soubor a ´ cne). ´ vytvoˇr´ı objektov´y model (elegantn´ı, ale naroˇ SAX (http://www.saxproject.org) – soubor se naˇc´ıta´ po ´ ´ eˇ elegantn´ı, ale rychle). ´ cˇ astech (men ´ Struktura dokumentu muˇ pomoc´ı DTD ˚ ze b´yt popsana ´ nebo XML Schema (XML syntaxe) (starˇs´ı, SGML format) ´ dokumentu. Pˇred prochazen´ ım lze dokument validovat. ´ dotazy pomoc´ı: Nad XML lze klast ´ XPath – nalezen´ı urˇciteho elementu souboru, ´ z + jednoduˇssˇ ´ı rozhran´ı, XPointer – toteˇ XQuery – SQL-like syntaxe.
ˇ e´ parsery pro C++ a pro QML. V QT jsou oddelen
XML soubory
Strana 18 / 32
SAX-like parser ´ ı udalost´ ´ Je zaloˇzen´y na zpracovan´ ı (naˇcten element). ´ a je nastaveno Kaˇzd´y naˇcten´y element je analyzovan ˇ rozhodnut´ı, co se ma´ udelat. Typicky definujeme reakce na situace, zˇ e naˇcten: ´ otev´ırac´ı element (analyzujeme jeho jmeno, parametry), ˇ ame ´ ´ ı uzav´ırac´ı element (nedel nic, nebo ukonˇc´ıme naˇc´ıtan´ skupiny dat).
´ prostˇrednictv´ım tˇr´ıd V QT je implementovan QXmlStreamReader a QXmlStreamWriter. Existuje take´ zjednoduˇsena´ nevaliduj´ıc´ı verze parseru – QXmlSimpleReader, QXmlSimpleWriter.
XML soubory
Strana 19 / 32
´ ˇ Zakladn´ ı princip cten´ ı 1 2 3 4 5 6
QFile file ( fileName ); if ( file . open ( QIODevice :: ReadOnly )) { QXmlStreamReader xmlReader ; xmlReader . setDevice (& file ); // / Nactu prvni token xmlReader . readNext ();
7 8 9 10 11 12 13 14 15 16 17
// / Cti dokud neni konec dokumentu while (! xmlReader . isEndDocument ()){ // / Je to pocatecni token ? if ( xmlReader . isStartElement ()){ // / Nacti jeho jmeno QString name = xmlReader . name (). toString (); if ( name == " square " ){ area = xmlReader . readElementText (). toInt (); id = xmlReader . attributes (). value ( " id " ). toInt ( ...
XML soubory
´ ´ Zakladn´ ı princip zapisu 1 2 3 4
QFile file ( fileName . split ( " // " ). at (1)); if ( file . open ( QIODevice :: WriteOnly )){ QXmlStreamWriter writer ; writer . setDevice (& file );
5 6 7
writer . w ri te St ar tD oc um en t (); writer . wr iteSta rtElem ent ( " results " );
8 9 10 11 12
writer . wr iteSta rtElem ent ( " result " ); writer . writeAttribute ( " game " ," 0 " ); writer . writeCharacters ( text ); writer . writeEndElement ();
13 14 15 16
writer . writeEndElement (); writer . writeEndDocument (); ...
Strana 20 / 32
XML soubory
Strana 21 / 32
Pˇr´ıklad XPath dotazu v QML – pˇr´ıklad ˇ Mejme RSS soubor s novinkami. 1 2 3 4 5 6 7 8 9 10 11 12 13 14
xml version = " 1.0 " encoding = " utf -8 " ? > < rss version = " 2.0 " > ... < channel > < item > < title > A blog post title > < pubDate > Sat , 07 Sep 2010 10:00:01 GMT pubDate > item > < item > < title > Another blog post title > < pubDate > Sat , 07 Sep 2010 15:35:01 GMT pubDate > item > channel > rss >
XML soubory
Strana 22 / 32
Pˇr´ıklad XPath dotazu v QML – dotaz ´ Ze souboru chceme vytahnout seznam novinek a zobrazit jej jako textova´ pole. Nadefinujeme dotaz extrahuj´ıc´ı potˇrebne´ elementy. 1 2
import QtQuick 2.0 import QtQuick . XmlListModel 2.0
3 4 5 6 7
XmlListModel { id : xmlModel source : " http :// www . mysite . com / feed . xml " query : " / rss / channel / item "
8
XmlRole { name : " title " ; query : " title / string () " } XmlRole { name : " pubDate " ; query : " pubDate / string () " }
9 10 11
}
XML soubory
Strana 23 / 32
Pˇr´ıklad XPath dotazu v QML – zobrazen´ı Nyn´ı muˇ ˚ zu pˇrevz´ıt v´ysledky, ktere´ XmlListModel vygeneruje a zobrazit je pomoc´ı repeateru, listview atp. 1 2 3 4 5
ListView { width : 180; height : 300 model : xmlModel delegate : Text { text : title + " : " + pubDate } }
Drag & drop
ˇ Obsah pˇredna´ sky 1
´ sky Obsah pˇrednaˇ
2
´ ı C++ kodu ´ Volan´
3
Dialogy
4
XML soubory
5
Drag & drop
6
´ er ˇ Zav
Strana 24 / 32
Drag & drop
Strana 25 / 32
ˇ ˇ polohu elementu. Drag & drop umoˇznuje menit ˚ ´ ı poloˇzek do Dlouhou dobu se v Qt pouˇz´ıva´ pro pˇridan´ widgetu˚ se seznamy atp. V QML jej lze aktivovat pro cele´ elementy. ´ U kaˇzdeho elementu, kter´y lze pˇresouvat mus´ıme definovat: ´ se pˇretahovan´y objekt bude zdrojov´y element, ve kterem ´ ´ nachazet napoˇcatku, ´ ´ pˇresun. c´ılov´y element, do ktereho je povoleno provest
´ Pro identifikaci povolene´ kombinace pˇresunovaneho objektu a c´ıle slouˇz´ı kl´ıcˇ .
Drag & drop
Strana 26 / 32
Drag & drop ˇ ˇ polohu elementu. Drag & drop umoˇznuje menit ˚ ´ ı poloˇzek do Dlouhou dobu se v Qt pouˇz´ıva´ pro pˇridan´ widgetu˚ se seznamy atp. V QML jej lze aktivovat pro cele´ elementy. ´ U kaˇzdeho elementu, kter´y lze pˇresouvat mus´ıme definovat: ´ se pˇretahovan´y objekt bude zdrojov´y element, ve kterem ´ ´ nachazet napoˇcatku, ´ ´ pˇresun. c´ılov´y element, do ktereho je povoleno provest
´ Pro identifikaci povolene´ kombinace pˇresunovaneho objektu a c´ıle slouˇz´ı kl´ıcˇ .
Drag & drop
Strana 27 / 32
Drag & drop – zdroj a pˇresouvany´ objekt 1 2 3 4 5 6 7 8 9 10 11 12
Item { id : root property string colorKey ... MouseArea { id : mouseArea ... // kam lze pretahovat drag . target : tile // kam se ma element umistit pokud to nevyjde onReleased : parent = tile . Drag . target !== null ? tile . Drag . target : root
13 14 15
Rectangle { ...
Drag & drop
Drag & drop – pˇresouvany´ objekt 1 2 3
Rectangle { id : tile width : 64; height : 64
4 5 6 7 8 9 10 11 12 13
// identifikacni klic pro d & d // colorKey byla definovana vyse Drag . keys : [ colorKey ] // jaka cast objektu je aktivni pro d & d Drag . active : mouseArea . drag . active // kde se ma objekt zachytit Drag . hotSpot . x : 32 Drag . hotSpot . y : 32 ...
Strana 28 / 32
Drag & drop
Drag & drop – c´ıl 1 2 3 4
DropArea { id : dragTarget property string colorKey keys : [ colorKey ]
5 6 7 8 9 10 11 12 13 14 15 16 17
Rectangle { id : dropRectangle anchors . fill : parent color : colorKey states : [ State { when : dragTarget . containsDrag PropertyChanges { target : dropRectangle color : " grey " } }
Strana 29 / 32
Drag & drop
Strana 30 / 32
Drag & drop – pouˇzit´ı 1 2 3 4 5 6 7 8 9 10 11 12 13
// cilova pozice kompatibilibni s pretahovanym // objektem - ma stejny klic DropTile { colorKey : " red " x : parent . width - width } // cilova pozice nekompatibilibni s pretahovanym // objektem - ma jiny klic DropTile { colorKey : " blue " x : parent . width - width y : parent . height - height }
14 15 16
// pretahovany objekt DragTile { colorKey : " red " }
´ er ˇ Zav
Strana 31 / 32
ˇ Obsah pˇredna´ sky 1
´ sky Obsah pˇrednaˇ
2
´ ı C++ kodu ´ Volan´
3
Dialogy
4
XML soubory
5
Drag & drop
6
´ er ˇ Zav
´ er ˇ Zav
Strana 32 / 32
Shrnut´ı ˇ ´ ´ ren´ı Dnes jsme si proˇsli nekolik temat duleˇ ˚ zit´ych pro vytvaˇ pokroˇcil´ych QML aplikac´ı: ´ ı C++ kodu ´ volan´ z QML, ˇ souboru), tvorbu dialogu˚ (nejen pro v´yber ˚ ´ s QML soubory, praci drag & drop technologii.