This document discusses using Qt Quick to recreate the UI of a TV streaming application, including configuring Qt Creator, creating views with ListView and PathView, using models and delegates, embedding QML in C++ applications, dynamically loading QML pages, and implementing a stack to navigate between pages.
1. Qt Quick in Depth
Lorenzo Mancini (lmancini@develer.com)
2. Qt Quick: a case study
Remake of Vodafone's TVConnect UI
Developed to demonstrate QQ's:
Conciseness
Performance
Overall toolchain
3. Qt Creator configuration
New Qt Quick Application
Integrate with Mercurial
Test the Application Viewer
Create a new run configuration
Projects->Run
qmlviewer %{CurrentDocument:FilePath}
We'll use this to test single pages
4. Qt Creator configuration
Enable QML debugging
Projects->Build
Build Steps->Link QML debugging library
(Rebuild all)
You only have to do all this once
This is all saved in .pro.user file
5. The Home menu
Background image
No states
Series of icons following a path
6. QML Views
List visualization for models
Models provide homogeneous data
Each data is represented by delegates
Interesting properties:
model
highlight
delegate
7. ListView
Standard QML View
Lays delegates in a list
A ListView in practice
Place it on view
Add a Model
Define a Delegate
E.g. Component / Column / Image + Text
11. PathView
Standard QML View
Defines a path that items follow
A PathView in practice
Place it on view
Add a Model
Define a Delegate
Define a Path
14. QML in C++ applications
Use QDeclarativeView to embed QML
QGraphicsView subclass, QWidget's as well
Useful to add QML features on top of
already existing applications
Keep an eye on startup time and memory
usage
14
15. QML in C++ applications
QML functions can be called via
QMetaObject::invokeMethod()
QML objects can emit signals that C++
code can QObject::connect()
→ you can define an interface for QML
objects
C++ properties / signals / slots are
exposed to QML via the Meta Object
System
15
16. QML Models in C++
QML doesn't have direct access to
hardware
What if we want to retrieve a list of
channel from a TV tuner?
We can subclass QAbstractItemModel,
implement the desired model in C++ and
use it from QML.
16
17. The TV menu
Two states:
TV only
overlay on screen
A channel list (reusable component)
A C++ model to retrieve channels
17
18. Putting it all together
Fast forward: we have several QML files,
one for each page
We would like to “instantiate” and load a
QML file on-the-fly
18
19. Dynamic Object Management
Dynamic object creation from Javascript
Qt.createComponent(url) → Component
Component.createObject(parent) → inst
The QML file can be fetched over the
network
Great for implementing live widgets!
… but the fetch is asynchronous: how do I know
when it's finished?
19
20. Dynamic Object Management
function createObject() {
component = Qt.createComponent("Sprite.qml");
if (component.status == Component.Ready)
finishCreation();
else
component.statusChanged.connect(finishCreation);
}
function finishCreation() {
if (component.status == Component.Ready) {
sprite = component.createObject(appWindow);
// …
}
}
20
21. A stack of pages
In most STBs, pages are in a stack
Entering a page → push
Previous page → pop
Panic button (home menu) → clear
We need a persistent global state for this
21
22. Stack implementation
// Stack.js
var stack = []
// Create a QML object from a given filename and push it on the stack
function openPage(filename) {
var page_c = Qt.createComponent(filename)
var page = page_c.createObject(root_window)
stack.push(page)
return page
}
// Page.qml
Import “stack.js” as Stack
Page {
Keys.onReturnPressed: {
Stack.openPage(“tvmenu.qml”)
}
}
22
23. Stack implementation
Sounds great! ...But alas, it doesn't work
A new execution context is created for the use of
the importing Component only
QML JS can't modify global object
members either
.pragma library
Placed at the top of a JS module, tells QML that
this module is stateless, so it's instance can
freely shared
Handle with care
23