Replacing SDL with Qt/QML
LinuxMCE is an open-source home automation platform based
upon Kubuntu. It originated as a closed source commercial
offering that was eventually open-sourced by PlutoHome Inc. Its
goal was to integrate all aspects of the home into one unified
user interface. As technology and design paradigms have
changed, the user interface has not, leading to the examination
of new GUI development avenues. In this talk, I will explore
what it takes to take a project like this, from an old ui paradigm
to a new one:Qt / QML
*
www.ics.com
Replacing SDL with Qt/QML
●
Gather your resources
○ Users, Developers
○ Docs
○ Original design documents.
It is key to try and develop a knowledge-base for insights into the
existing architecture. Knowing why something was done a certain way can be a great boost when porting feature sets to a new ui technology. Know what the basic application goals are and seek to make sure this functionality is ported over. Users dont always know when something is new, but they always notice when something is gone.
Replacing SDL with Qt/QML
●
Figure out what it is you need and how you need it
○ How does the api interaction work?
○ Does it fit into the architecture of the new application?
■ If not, how best to make it work?
When dealing with creating a new application on top of an existing api, data structures and methods of communication are the first thing that should be investigated. Are the existing methods compatible with the
new Qt / QML application? Is there room for improvement. Are alternate methods availible. The constraints of every system differ, and this is
why exploring all options is an important, if time consuming, step.
Working with the API
*
www.ics.com
Replacing SDL with Qt/QML
In data driven applications, Qt already has many container
classes to utilize for data
QAbstractListmodel / QAbstractItemModel / QML Listmodel QList<QObject*>
QMap
And more!
Investigate what type will be the best match for the source they are coming from.
Replacing SDL with Qt/QML
● Benefits
○ Can save time by not needing to write new classes.
○ Signals and slots become available from legacy api.
○ More flexibility
● Drawbacks / Pitfalls
○ Diamond inheritance problems
○ Could break api for legacy applications
*
www.ics.com
Replacing SDL with Qt/QML
Example: Main application
class qOrbiter_Command : public Command_Impl,public QObject
Example: Qml plugin for providing media over the network is a C++ plugin.
class qMediaPlayer_Command : public Command_Impl , public QObject
In Both instances, it was necessary to avoid a diamond inheritance problem, so I by
examining the base classes, I was able to subclass QObject, giving it all the power of Qt.
Subclassing QObject
Replacing SDL with Qt/QML
Explore the different methods of connecting the two pieces together. Dont stop at what seems to be the 1st working solution, but explore different methods and compare the effectiveness of each.
Options include
● Passing the api object by reference to the application
● Connecting data, commands, and events by signals and slots
Other considerations when deciding this include:
● Who needs access to the api? The main superclass, or its members
also?
● Will there be the need for direct communication.
● Should the super-class be split into other classes for more flexiblity?
*
www.ics.com
Replacing SDL with Qt/QML
Styling the application, and how you plan to do it is an important
architectural decision. Will it support one style or multiple? Will these styles only originate from the developers, or will users be able to
customize the look and feel as well? These are important questions, because they will ultimately decide how you create, work with, and
deploy qml files.
Replacing SDL with Qt/QML
QtObject{
id:aeonstyle
objectName: "orbiter_style"
//skin description
property string skincreator: "Jason Richardson (aka merkur2k)"
property string skinname: "Aeon"
property string skindir: "aeon"
property string skindescription: "Inspired by the XBMC skin of the same name"
property string skinversion: "1.0"
property string skinvariation: "Desktop 720p"
property string maincolor: "aliceblue"
property string accentcolor: "lightsteelblue"
}
*
www.ics.com
Replacing SDL with Qt/QML
When employing a theming engine that allows the dynamic manipulation of the styles, its key to remember a few things:
● Its generally wise to create a fallback page that loads in the case of an
unrecoverable QML error. Instead of the user looking at a white
screen, they should get input that allows them to report it back to you.
● Layout a template that includes some form of metadata on the theme
itself.
● In building and deploying for multiple architectures or versions, utilize
the Project.pro file to customize your deployment files / current QML files.
Replacing SDL with Qt/QML
● Create a library of standard api handlers or interfaces, and encourage
designers to utilize it. Its a lot easier to add a custom component to an element rather than setting up the mouse area, remembering what
function to call, and then adding the parameters. In most cases, data is coming from a datamodel and the parameter names and such are defined in advance. Creating a set of standard components simplifies the functional part of things
MouseArea{ anchors.fill:parent onClicked:mySlot(param, param2) }
Visual Theming
MySlotHandler{}is a component based on the mouse
area with the params pre-filled in. A user just need to instantiate it to give the
*
www.ics.com
Replacing SDL with Qt/QML
In the case of dealing with a system that requires interaction with a remote server / datasource, its a wise idea to try and implement the communication part in a manner that doesnt block the GUI.
● Web based datasources operate asynchronously. You can request
data and it will be processed without blocking the main thread, and thusly the gui.
● C++ datasources however do not make asynchronous calls unless
you implement an architecture capable of that. Utilizing QThread can be immensely helpful here, allowing the server object to go at its own (hopefully not to slow!) pace.
Replacing SDL with Qt/QML
Some of the Qt Classes utilized in the LinuxMCE application are:
● QDeclarativeView / QQuickView ● QApplication / QCoreApplication ● QTcpServer ● QTcpSocket ● QRegExp ● QObject ● QAbstractImageProvider / QQmlImageProvider ● OpenGl ● Phonon / QtMultimedia ● Webkit ● QFile, QDir ● QProcess QAbstractListmodel
Qt Class Roll Call
● QDataStream
● QList<QObject*>
● QMap
*
www.ics.com
Replacing SDL with Qt/QML
Media integration can be one of the more complex points of integration of a new user interface. With many ways to consume media from a
technical standpoint, planning this integration is key.
● Will media be incorporated directly into my application
● What are the capabilities of my target platform
● Will I need windowing control to place playback windows in the right
locations?
● How am i interacting with the media sources, catalog?
○ How can i abstract the source / catalog integration to make it easier
for designers to utilize?
Replacing SDL with Qt/QML
{ pCell= it->second;
const char *pPath = pCell->GetImagePath(); filePath = QString::fromUtf8(pPath);
fk_file = pCell->GetValue();
cellTitle = QString::fromUtf8(pCell->m_Text);
index = pDataGridTable->CovertColRowType(it->first).first; if (pPath ) { cellImg = getfileForDG(pPath); }
else
{ cellImg.load(":/icons/icon.png"); }
emit addItem(new gridItem(fk_file, cellTitle, filePath, index, cellImg)); }
*
www.ics.com
Replacing SDL with Qt/QML
Converting a legacy application that utilizes and older ui technology can be quite the undertaking. But with a planned, measured approach, it can be done expeditiously, and done well.
● Find as many original system designers as you can
● Spend time examining the existing architecture, and where your new
application can fit in
○ This includes the API
■ For web based api's _should_ be less of a challenge
■ For other methods, don't be afraid to experiment with sub-classing
QObject
● Plan your QML architecture from the start.
○ Decide if you are going to use multiple styles, or one