SlideShare a Scribd company logo
Practical QML
Burkhard Stubert
Chief Engineer, Embedded Use
www.embeddeduse.com
Contents

 Key Navigation
 Dynamic Language Change
 Themes
Key Navigation in Cars

Navigation clusters for controlling
in-vehicle infotainment systems
Key Navigation in Harvesters

Driver terminals for
Harvesters and tractors
Active Focus
 QML item needs active focus to receive key

events
 Only single item has active focus
 Property Item.activeFocus (read-only)
 True if item has active focus
 Function Item.forceActiveFocus()
 Forces item to have active focus
 Property Item.focus
 Requests active focus when set to true
Focus Scopes
 Component FocusScope
 Controls which child item gets active focus
 Needed for introducing new components with key
handling
 When FocusScope receives active focus:
 Last item to request focus gains active focus
 When last item is FocusScope, active focus is
forwarded to FocusScope
Who gains active focus?
FocusScope A
FocusScope B1
Rectangle C1

Rectangle C2

focus: true

FocusScope B2

focus: true

Rectangle D1

Rectangle D1
focus: true
Recap: KeyNavigation
Attached Property
Tab
Backtab

FlagButton {
id: france
KeyNavigation.backtab: spain
KeyNavigation.tab: italy
Crossing FocusScopes with
KeyNavigation
focus: true
focus: true

 Enclose flag rows with FocusScope as preliminary

for FlagRow component
 What happens when crossing to other flag row?
Crossing FocusScopes with
KeyNavigation (2)

 KeyNavigation stops when crossing to other

FocusScope
 Reason: FocusScope changes focus instead of
activeFocus
Crossing Focus Scopes
with KeyNavigation (3)
 Solution:

FlagButton {
id: italy
KeyNavigation.backtab: france
KeyNavigation.tab: uk
Keys.onTabPressed: uk.forceActiveFocus()
 KeyNavigation not suited for components
 Reason: top item of component always a FocusScope
 KeyNavigation forces monolithic code
Introducing a Generic
Cursor Component
 Forces guiding the solution
 Write code for state machine, visual items, key and
mouse handling only once
 Use only one way to move active focus:
forceActiveFocus()
 Tab and backtab chains must take component
structures into account
Moving Active Focus in Item
Hierarchy
FlagRow.row0

FlagRow.row1

FlagButton.france

FlagButton.italy

FlagButton.uk

Cursor.france

Cursor.italy

Cursor.italy

Tab

Tab

 KeyNavigation structure needs four properties:

tabUp/tabDown and backtabUp/backtabDow
Introducing New Attached
Property KeyNav
 KeyNav
 tabUp : Item
 backtabUp: Item

tabDown: Item
backtabDown: Item

 Attached properties ≈ multipe inheritance
 Save us from declaring four properties in each QML
component
 Example use in middle FlagButton
FlagButton {
id: flag1
KeyNav.backtabUp: flag0.KeyNav.backtabDown
KeyNav.tabUp: flag2.KeyNav.tabDown
}
Handling the Return Key in
Cursor
signal released()
Keys.onPressed: {
if (event.key === Qt.Key_Return) {
root.state = “pressed”
event.accepted = true
}
}
Keys.onReleased: {
if (event.key === Qt.Key_Return) {
root.state = “focused”
root.released()
event.accepted = true
}
}

Make key and mouse
handling look the same for
clients

Also add “pressed” State to
states property
Move out of if-clause to
stop default key handling of
ListView (Up and Down)

Forward in Cursor instance
of FlagButton:
onReleased: root.release()
Key Navigation in ListViews
 Forces guiding the solution
 ListView item has no way to find out previous and
next item
• Cannot use forceActiveFocus()

 Changing currentIndex changes focus
• Reimplement doTab() and doBacktab() for Cursor

 Special cases for moving the active focus into the
ListView with Tab and Backtab
• Implement doTab() and doBacktab() for ListView
Key Navigation in ListViews
(2)
 Extract doTab() and doBacktab() from Cursor

into ButtonCursor and ListViewItemCursor

Cursor

ButtonCursor

ListViewItemCursor

doTab() and doBacktab()
use forceActiveFocus()
to move active focus

doTab() and doBacktab()
change currentIndex to
move active focus
Key Navigation in ListViews
(3)
 Every ListView inherits from BaseListView

 BaseListView provides tabbing and backtabbing

into list view
In BaseListView:
function doTab() {
root.positionViewAtIndex(0,
ListView.Beginning)
root.currentIndex = 0
root.forceActiveFocus()
}

Ensure that first item will
be visible
Request focus for first item

Forces active focus on
ListView, which passes it to
first item
Adding Mouse Handling to
Cursor Components
MouseArea {
anchors.fill: parent
onPressed: {
root.doMousePress()
root.state = “pressed”
mouse.accepted = true
}
onReleased: {
if (root.activeFocus) {
root.state = “focused”
root.released()
}
mouse.accepted = true
}
}

Active focus on item
pressed, no dereferencing
of tab chain needed
Mouse press different for
buttons and list view items

Do not execute “release”
when item lost
focus, e.g., when error
dialog opened
Adding Mouse Handling to
Cursor Components (2)
In ButtonCursor:
function doMousePress() {
root.forceActiveFocus()
}
index provided by delegate
in ListView

In ListViewItemCursor:
function doMousePress() {
delegateRoot.ListView.view.currentIndex = index
delegateRoot.ListView.view.forceActiveFocus()
}
For the case when the flag
row has active focus and
the user clicks in list view.
Avoids multiple cursors.
Contents

 Key Navigation
 Dynamic Language Change
 Themes
Dynamic Language Change
Dynamic Language Change
for QWidgets
 QCoreApplication::installTranslator() sends

LanguageChange event to application object
 QApplication::event() posts LanguageChange
event to every top-level widget (QWidget*)
 QWidget::event() calls changeEvent() on the
widget and sends LanguageChange event to all
its children
 changeEvent() is called on every widget in the widget
tree rooted at a top-level widget
Problems in QML
 Not a single QWidget in QML applications
 Not even QQuickView derives from QWidget
 QApplication not used in QML applications
 Note: QApplication derives from QGuiApplication

Need to rebuild LanguageChange
infrastructure in QML
Dynamic Language Change
in QML
 TranslationManager emits signal

languageChanged()
 Qt/C++ classes (e.g., list models) connect signal
with their retranslate() slot
 Every qsTr() call in QML must be reevaluated
when signal emitted
Changing the Language
 TranslationManager::setLanguage(language)
 Load translation file for language in QTranslator
 Remove old translator from application
 Install new translator in application
 emit languageChanged(language)

 Call setLanguage() before main view of

application is created
 Call setLanguage() when user changes
language
Retranslating Qt/C++
Models
 Equivalent to reimplementing changeEvent()

and calling retranslateUi()
 In constructor of model class:
connect(TranslationManager::instance(),
SIGNAL(languageChanged(QString)),
this,
SLOT(retranslate(QString)));
Retranslating Qt/C++
Models (2)
void BiggestCitiesModel::retranslate(const QString &language)
{
emit titleChange();
CityDatabase::instance()->retranslate(language);
emit dataChanged(index(0), index(m_cities.count() - 1));
}
Notify QML ListView that
all its items have changed
and need reloading
Notify QML code that
title property has
changed
QML calls title(), which
returns tr(rawTitle())

Delegate retranslation, as
model is “view” on
database
Retranslating Qt/C++
Models (3)
const char *CityDatabase::m_strings[][2] = {
{ QT_TR_NOOP(“Munich”), QT_TR_NOOP(“Bavaria”) }, …
void CityDatabase::retranslate(const QString &language) {
if (m_currentLanguage != language) {
for (int i = 0; i < m_cities.count(); ++i) {
m_cities[i]->setName(tr(m_strings[i][0]));
…
}
m_currentLanguage = language;
}
Reset visible members
}

Guard against multiple
“views” (e.g., German
cities, British cities)
requesting retranslation
to same language

(e.g., city name, state)
with new translation of
raw string
Reevaluating qsTr on
Language Change
Text {
text: qsTr(“City:”) + g_tr.languageChanged
…
}

 Use Property Binding:
 Whenever g_tr.languageChanged changes, text must
be reevaluated:
 qsTr() is called and returns translation for new
language
Reevaluating qsTr on
Language Change (2)
In TranslationManager:
Q_PROPERTY(QString languageChanged
READ emptyString
NOTIFY languageChanged)

QString emptyString() const {
return “”;
}
Empty string can be appended
to translated string without
changing anything

Emitting this signal forces QML
to call emptyString(), the READ
method of languageChanged
property
Reevaluating qsTr on
Language Change (3)
On instance of QQuickView:
view->rootContext()->setContextProperty(
“g_tr”, TranslationManager::instance());

Makes pointer to
TranslationManager globally
available in QML under name g_tr
Contents

 Key Navigation
 Dynamic Language Change
 Themes
Dynamic Theme Change
Theming QML Code
Rectangle {
color: index % 2 === 0 ?
“#1E90FF” :
“#00BFFF”

Row {
Text {
text: city.name
color: “#191970”

Unthemed

Rectangle {
color: index % 2 === 0 ?
g_theme.listViewItem.
backgroundColor :
g_theme.listViewItem.
backgroundColorAlt
Row {
Text {
text: city.name
color: g_theme.listViewItem.
textColor

Themed
Implementing the Themes
QtObject {
property QtObject listViewItem : QtObject {
property color backgroundColor: “#1E90FF”
property color backgroundColorAlt: “#00BFFF”
property color textColor: “#191970”
}

QtObject {
property QtObject listViewItem : QtObject {
property color backgroundColor: “#A5A5A5”
property color backgroundColorAlt: “#818181”
property color textColor: “#1E1E1E”
}
Changing Themes
In top-level QML item (main.qml)

Global variable accessible from
everywhere in QML

property alias g_theme: loader.item
Loader { id: loader }
Set theme on start-up
Component.onCompleted: {
loader.source = Qt.resolveUrl(“BlueTheme.qml”)
}
QQuickView forwards signal
Connections {
themeChanged(QString theme)
target: g_viewer
onThemeChanged: {
loader.source = Qt.resolvedUrl(theme + “Theme.qml”)
}
}
The End

Thank you!

More Related Content

What's hot

Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7
Pasi Kellokoski
 
Best Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IVBest Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IV
ICS
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI development
ICS
 
Qt Qml
Qt QmlQt Qml
Qt Qml
Steven Song
 
Introduction to QML
Introduction to QMLIntroduction to QML
Introduction to QML
Alan Uthoff
 
UI Programming with Qt-Quick and QML
UI Programming with Qt-Quick and QMLUI Programming with Qt-Quick and QML
UI Programming with Qt-Quick and QML
Emertxe Information Technologies Pvt Ltd
 
Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2
Emertxe Information Technologies Pvt Ltd
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
ICS
 
Qt Internationalization
Qt InternationalizationQt Internationalization
Qt Internationalization
ICS
 
Qt Design Patterns
Qt Design PatternsQt Design Patterns
Qt Design Patterns
Ynon Perek
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt Quick
ICS
 
Qt for beginners
Qt for beginnersQt for beginners
Qt for beginners
Sergio Shevchenko
 
Qt Application Programming with C++ - Part 1
Qt Application Programming with C++ - Part 1Qt Application Programming with C++ - Part 1
Qt Application Programming with C++ - Part 1
Emertxe Information Technologies Pvt Ltd
 
Lessons Learned from Building 100+ C++/Qt/QML Devices
Lessons Learned from Building 100+ C++/Qt/QML DevicesLessons Learned from Building 100+ C++/Qt/QML Devices
Lessons Learned from Building 100+ C++/Qt/QML Devices
ICS
 
Qt 5 - C++ and Widgets
Qt 5 - C++ and WidgetsQt 5 - C++ and Widgets
Qt 5 - C++ and Widgets
Juha Peltomäki
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
Ynon Perek
 
Qt Workshop
Qt WorkshopQt Workshop
Qt Workshop
Johan Thelin
 
PlantUML introduction
PlantUML introductionPlantUML introduction
PlantUML introduction
Richard Ruiter
 
Introduction to Kotlin coroutines
Introduction to Kotlin coroutinesIntroduction to Kotlin coroutines
Introduction to Kotlin coroutines
Roman Elizarov
 
Introduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene GraphIntroduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene Graph
ICS
 

What's hot (20)

Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7
 
Best Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IVBest Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IV
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI development
 
Qt Qml
Qt QmlQt Qml
Qt Qml
 
Introduction to QML
Introduction to QMLIntroduction to QML
Introduction to QML
 
UI Programming with Qt-Quick and QML
UI Programming with Qt-Quick and QMLUI Programming with Qt-Quick and QML
UI Programming with Qt-Quick and QML
 
Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
 
Qt Internationalization
Qt InternationalizationQt Internationalization
Qt Internationalization
 
Qt Design Patterns
Qt Design PatternsQt Design Patterns
Qt Design Patterns
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt Quick
 
Qt for beginners
Qt for beginnersQt for beginners
Qt for beginners
 
Qt Application Programming with C++ - Part 1
Qt Application Programming with C++ - Part 1Qt Application Programming with C++ - Part 1
Qt Application Programming with C++ - Part 1
 
Lessons Learned from Building 100+ C++/Qt/QML Devices
Lessons Learned from Building 100+ C++/Qt/QML DevicesLessons Learned from Building 100+ C++/Qt/QML Devices
Lessons Learned from Building 100+ C++/Qt/QML Devices
 
Qt 5 - C++ and Widgets
Qt 5 - C++ and WidgetsQt 5 - C++ and Widgets
Qt 5 - C++ and Widgets
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Qt Workshop
Qt WorkshopQt Workshop
Qt Workshop
 
PlantUML introduction
PlantUML introductionPlantUML introduction
PlantUML introduction
 
Introduction to Kotlin coroutines
Introduction to Kotlin coroutinesIntroduction to Kotlin coroutines
Introduction to Kotlin coroutines
 
Introduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene GraphIntroduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene Graph
 

Similar to Practical QML - Key Navigation, Dynamic Language and Theme Change

From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Codemotion
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
06 win forms
06 win forms06 win forms
06 win forms
mrjw
 
4.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.15
4.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.154.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.15
4.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.15
Rajes Wari
 
Practicalfileofvb workshop
Practicalfileofvb workshopPracticalfileofvb workshop
Practicalfileofvb workshop
dhi her
 
Flex 4 tips
Flex 4 tipsFlex 4 tips
Flex 4 tips
Nitin Khattar
 
engineeringdsgtnotesofunitfivesnists.ppt
engineeringdsgtnotesofunitfivesnists.pptengineeringdsgtnotesofunitfivesnists.ppt
engineeringdsgtnotesofunitfivesnists.ppt
sharanyak0721
 
IT104 Week 4 - Module/Function
IT104 Week 4 - Module/FunctionIT104 Week 4 - Module/Function
IT104 Week 4 - Module/Function
Cornerstone University
 
intro_gui
intro_guiintro_gui
intro_gui
filipb2
 
Visualbasic tutorial
Visualbasic tutorialVisualbasic tutorial
Visualbasic tutorial
Andi Simanjuntak
 
Csphtp1 12
Csphtp1 12Csphtp1 12
Csphtp1 12
HUST
 
WPF Controls
WPF ControlsWPF Controls
WPF Controls
Doncho Minkov
 
Controls events
Controls eventsControls events
Controls events
Dalwin INDIA
 
Treinamento Qt básico - aula III
Treinamento Qt básico - aula IIITreinamento Qt básico - aula III
Treinamento Qt básico - aula III
Marcelo Barros de Almeida
 
Android 3
Android 3Android 3
Android 3
Robert Cooper
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
Katy Slemon
 
MEngine Advanced
MEngine AdvancedMEngine Advanced
MEngine Advanced
euming
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to Javascript
Walid Ashraf
 
MVVM with Kotlin: Making iOS and Android apps as similar as possible
MVVM with Kotlin: Making iOS and Android apps as similar as possibleMVVM with Kotlin: Making iOS and Android apps as similar as possible
MVVM with Kotlin: Making iOS and Android apps as similar as possible
QuickBird Studios GmbH
 
JavaScript
JavaScriptJavaScript
JavaScript
Bharti Gupta
 

Similar to Practical QML - Key Navigation, Dynamic Language and Theme Change (20)

From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
06 win forms
06 win forms06 win forms
06 win forms
 
4.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.15
4.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.154.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.15
4.7.14&amp;17.7.14&amp;23.6.15&amp;10.9.15
 
Practicalfileofvb workshop
Practicalfileofvb workshopPracticalfileofvb workshop
Practicalfileofvb workshop
 
Flex 4 tips
Flex 4 tipsFlex 4 tips
Flex 4 tips
 
engineeringdsgtnotesofunitfivesnists.ppt
engineeringdsgtnotesofunitfivesnists.pptengineeringdsgtnotesofunitfivesnists.ppt
engineeringdsgtnotesofunitfivesnists.ppt
 
IT104 Week 4 - Module/Function
IT104 Week 4 - Module/FunctionIT104 Week 4 - Module/Function
IT104 Week 4 - Module/Function
 
intro_gui
intro_guiintro_gui
intro_gui
 
Visualbasic tutorial
Visualbasic tutorialVisualbasic tutorial
Visualbasic tutorial
 
Csphtp1 12
Csphtp1 12Csphtp1 12
Csphtp1 12
 
WPF Controls
WPF ControlsWPF Controls
WPF Controls
 
Controls events
Controls eventsControls events
Controls events
 
Treinamento Qt básico - aula III
Treinamento Qt básico - aula IIITreinamento Qt básico - aula III
Treinamento Qt básico - aula III
 
Android 3
Android 3Android 3
Android 3
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdf
 
MEngine Advanced
MEngine AdvancedMEngine Advanced
MEngine Advanced
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to Javascript
 
MVVM with Kotlin: Making iOS and Android apps as similar as possible
MVVM with Kotlin: Making iOS and Android apps as similar as possibleMVVM with Kotlin: Making iOS and Android apps as similar as possible
MVVM with Kotlin: Making iOS and Android apps as similar as possible
 
JavaScript
JavaScriptJavaScript
JavaScript
 

More from Burkhard Stubert

Webinar: Building Embedded Applications from QtCreator with Docker
Webinar: Building Embedded Applications from QtCreator with DockerWebinar: Building Embedded Applications from QtCreator with Docker
Webinar: Building Embedded Applications from QtCreator with Docker
Burkhard Stubert
 
A Deep Dive into QtCanBus
A Deep Dive into QtCanBusA Deep Dive into QtCanBus
A Deep Dive into QtCanBus
Burkhard Stubert
 
Using Qt under LGPLv3
Using Qt under LGPLv3Using Qt under LGPLv3
Using Qt under LGPLv3
Burkhard Stubert
 
Qt World Summit 2017: Qt vs. Web - Total Cost of Ownership
Qt World Summit 2017: Qt vs. Web - Total Cost of OwnershipQt World Summit 2017: Qt vs. Web - Total Cost of Ownership
Qt World Summit 2017: Qt vs. Web - Total Cost of Ownership
Burkhard Stubert
 
Burkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert: Project Portfolio and ExpertiseBurkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert
 
Landmaschinen-HMIs für 2016 (in German)
Landmaschinen-HMIs für 2016 (in German)Landmaschinen-HMIs für 2016 (in German)
Landmaschinen-HMIs für 2016 (in German)Burkhard Stubert
 
Developing Driver Terminal for Forage Harvester with QML and Qt
Developing Driver Terminal for Forage Harvester with QML and QtDeveloping Driver Terminal for Forage Harvester with QML and Qt
Developing Driver Terminal for Forage Harvester with QML and Qt
Burkhard Stubert
 

More from Burkhard Stubert (7)

Webinar: Building Embedded Applications from QtCreator with Docker
Webinar: Building Embedded Applications from QtCreator with DockerWebinar: Building Embedded Applications from QtCreator with Docker
Webinar: Building Embedded Applications from QtCreator with Docker
 
A Deep Dive into QtCanBus
A Deep Dive into QtCanBusA Deep Dive into QtCanBus
A Deep Dive into QtCanBus
 
Using Qt under LGPLv3
Using Qt under LGPLv3Using Qt under LGPLv3
Using Qt under LGPLv3
 
Qt World Summit 2017: Qt vs. Web - Total Cost of Ownership
Qt World Summit 2017: Qt vs. Web - Total Cost of OwnershipQt World Summit 2017: Qt vs. Web - Total Cost of Ownership
Qt World Summit 2017: Qt vs. Web - Total Cost of Ownership
 
Burkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert: Project Portfolio and ExpertiseBurkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert: Project Portfolio and Expertise
 
Landmaschinen-HMIs für 2016 (in German)
Landmaschinen-HMIs für 2016 (in German)Landmaschinen-HMIs für 2016 (in German)
Landmaschinen-HMIs für 2016 (in German)
 
Developing Driver Terminal for Forage Harvester with QML and Qt
Developing Driver Terminal for Forage Harvester with QML and QtDeveloping Driver Terminal for Forage Harvester with QML and Qt
Developing Driver Terminal for Forage Harvester with QML and Qt
 

Recently uploaded

Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
Claudio Di Ciccio
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
Pixlogix Infotech
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 

Recently uploaded (20)

Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 

Practical QML - Key Navigation, Dynamic Language and Theme Change

  • 1. Practical QML Burkhard Stubert Chief Engineer, Embedded Use www.embeddeduse.com
  • 2. Contents  Key Navigation  Dynamic Language Change  Themes
  • 3. Key Navigation in Cars Navigation clusters for controlling in-vehicle infotainment systems
  • 4. Key Navigation in Harvesters Driver terminals for Harvesters and tractors
  • 5. Active Focus  QML item needs active focus to receive key events  Only single item has active focus  Property Item.activeFocus (read-only)  True if item has active focus  Function Item.forceActiveFocus()  Forces item to have active focus  Property Item.focus  Requests active focus when set to true
  • 6. Focus Scopes  Component FocusScope  Controls which child item gets active focus  Needed for introducing new components with key handling  When FocusScope receives active focus:  Last item to request focus gains active focus  When last item is FocusScope, active focus is forwarded to FocusScope
  • 7. Who gains active focus? FocusScope A FocusScope B1 Rectangle C1 Rectangle C2 focus: true FocusScope B2 focus: true Rectangle D1 Rectangle D1 focus: true
  • 8. Recap: KeyNavigation Attached Property Tab Backtab FlagButton { id: france KeyNavigation.backtab: spain KeyNavigation.tab: italy
  • 9. Crossing FocusScopes with KeyNavigation focus: true focus: true  Enclose flag rows with FocusScope as preliminary for FlagRow component  What happens when crossing to other flag row?
  • 10. Crossing FocusScopes with KeyNavigation (2)  KeyNavigation stops when crossing to other FocusScope  Reason: FocusScope changes focus instead of activeFocus
  • 11. Crossing Focus Scopes with KeyNavigation (3)  Solution: FlagButton { id: italy KeyNavigation.backtab: france KeyNavigation.tab: uk Keys.onTabPressed: uk.forceActiveFocus()  KeyNavigation not suited for components  Reason: top item of component always a FocusScope  KeyNavigation forces monolithic code
  • 12. Introducing a Generic Cursor Component  Forces guiding the solution  Write code for state machine, visual items, key and mouse handling only once  Use only one way to move active focus: forceActiveFocus()  Tab and backtab chains must take component structures into account
  • 13. Moving Active Focus in Item Hierarchy FlagRow.row0 FlagRow.row1 FlagButton.france FlagButton.italy FlagButton.uk Cursor.france Cursor.italy Cursor.italy Tab Tab  KeyNavigation structure needs four properties: tabUp/tabDown and backtabUp/backtabDow
  • 14. Introducing New Attached Property KeyNav  KeyNav  tabUp : Item  backtabUp: Item tabDown: Item backtabDown: Item  Attached properties ≈ multipe inheritance  Save us from declaring four properties in each QML component  Example use in middle FlagButton FlagButton { id: flag1 KeyNav.backtabUp: flag0.KeyNav.backtabDown KeyNav.tabUp: flag2.KeyNav.tabDown }
  • 15. Handling the Return Key in Cursor signal released() Keys.onPressed: { if (event.key === Qt.Key_Return) { root.state = “pressed” event.accepted = true } } Keys.onReleased: { if (event.key === Qt.Key_Return) { root.state = “focused” root.released() event.accepted = true } } Make key and mouse handling look the same for clients Also add “pressed” State to states property Move out of if-clause to stop default key handling of ListView (Up and Down) Forward in Cursor instance of FlagButton: onReleased: root.release()
  • 16. Key Navigation in ListViews  Forces guiding the solution  ListView item has no way to find out previous and next item • Cannot use forceActiveFocus()  Changing currentIndex changes focus • Reimplement doTab() and doBacktab() for Cursor  Special cases for moving the active focus into the ListView with Tab and Backtab • Implement doTab() and doBacktab() for ListView
  • 17. Key Navigation in ListViews (2)  Extract doTab() and doBacktab() from Cursor into ButtonCursor and ListViewItemCursor Cursor ButtonCursor ListViewItemCursor doTab() and doBacktab() use forceActiveFocus() to move active focus doTab() and doBacktab() change currentIndex to move active focus
  • 18. Key Navigation in ListViews (3)  Every ListView inherits from BaseListView  BaseListView provides tabbing and backtabbing into list view In BaseListView: function doTab() { root.positionViewAtIndex(0, ListView.Beginning) root.currentIndex = 0 root.forceActiveFocus() } Ensure that first item will be visible Request focus for first item Forces active focus on ListView, which passes it to first item
  • 19. Adding Mouse Handling to Cursor Components MouseArea { anchors.fill: parent onPressed: { root.doMousePress() root.state = “pressed” mouse.accepted = true } onReleased: { if (root.activeFocus) { root.state = “focused” root.released() } mouse.accepted = true } } Active focus on item pressed, no dereferencing of tab chain needed Mouse press different for buttons and list view items Do not execute “release” when item lost focus, e.g., when error dialog opened
  • 20. Adding Mouse Handling to Cursor Components (2) In ButtonCursor: function doMousePress() { root.forceActiveFocus() } index provided by delegate in ListView In ListViewItemCursor: function doMousePress() { delegateRoot.ListView.view.currentIndex = index delegateRoot.ListView.view.forceActiveFocus() } For the case when the flag row has active focus and the user clicks in list view. Avoids multiple cursors.
  • 21. Contents  Key Navigation  Dynamic Language Change  Themes
  • 23. Dynamic Language Change for QWidgets  QCoreApplication::installTranslator() sends LanguageChange event to application object  QApplication::event() posts LanguageChange event to every top-level widget (QWidget*)  QWidget::event() calls changeEvent() on the widget and sends LanguageChange event to all its children  changeEvent() is called on every widget in the widget tree rooted at a top-level widget
  • 24. Problems in QML  Not a single QWidget in QML applications  Not even QQuickView derives from QWidget  QApplication not used in QML applications  Note: QApplication derives from QGuiApplication Need to rebuild LanguageChange infrastructure in QML
  • 25. Dynamic Language Change in QML  TranslationManager emits signal languageChanged()  Qt/C++ classes (e.g., list models) connect signal with their retranslate() slot  Every qsTr() call in QML must be reevaluated when signal emitted
  • 26. Changing the Language  TranslationManager::setLanguage(language)  Load translation file for language in QTranslator  Remove old translator from application  Install new translator in application  emit languageChanged(language)  Call setLanguage() before main view of application is created  Call setLanguage() when user changes language
  • 27. Retranslating Qt/C++ Models  Equivalent to reimplementing changeEvent() and calling retranslateUi()  In constructor of model class: connect(TranslationManager::instance(), SIGNAL(languageChanged(QString)), this, SLOT(retranslate(QString)));
  • 28. Retranslating Qt/C++ Models (2) void BiggestCitiesModel::retranslate(const QString &language) { emit titleChange(); CityDatabase::instance()->retranslate(language); emit dataChanged(index(0), index(m_cities.count() - 1)); } Notify QML ListView that all its items have changed and need reloading Notify QML code that title property has changed QML calls title(), which returns tr(rawTitle()) Delegate retranslation, as model is “view” on database
  • 29. Retranslating Qt/C++ Models (3) const char *CityDatabase::m_strings[][2] = { { QT_TR_NOOP(“Munich”), QT_TR_NOOP(“Bavaria”) }, … void CityDatabase::retranslate(const QString &language) { if (m_currentLanguage != language) { for (int i = 0; i < m_cities.count(); ++i) { m_cities[i]->setName(tr(m_strings[i][0])); … } m_currentLanguage = language; } Reset visible members } Guard against multiple “views” (e.g., German cities, British cities) requesting retranslation to same language (e.g., city name, state) with new translation of raw string
  • 30. Reevaluating qsTr on Language Change Text { text: qsTr(“City:”) + g_tr.languageChanged … }  Use Property Binding:  Whenever g_tr.languageChanged changes, text must be reevaluated:  qsTr() is called and returns translation for new language
  • 31. Reevaluating qsTr on Language Change (2) In TranslationManager: Q_PROPERTY(QString languageChanged READ emptyString NOTIFY languageChanged) QString emptyString() const { return “”; } Empty string can be appended to translated string without changing anything Emitting this signal forces QML to call emptyString(), the READ method of languageChanged property
  • 32. Reevaluating qsTr on Language Change (3) On instance of QQuickView: view->rootContext()->setContextProperty( “g_tr”, TranslationManager::instance()); Makes pointer to TranslationManager globally available in QML under name g_tr
  • 33. Contents  Key Navigation  Dynamic Language Change  Themes
  • 35. Theming QML Code Rectangle { color: index % 2 === 0 ? “#1E90FF” : “#00BFFF” Row { Text { text: city.name color: “#191970” Unthemed Rectangle { color: index % 2 === 0 ? g_theme.listViewItem. backgroundColor : g_theme.listViewItem. backgroundColorAlt Row { Text { text: city.name color: g_theme.listViewItem. textColor Themed
  • 36. Implementing the Themes QtObject { property QtObject listViewItem : QtObject { property color backgroundColor: “#1E90FF” property color backgroundColorAlt: “#00BFFF” property color textColor: “#191970” } QtObject { property QtObject listViewItem : QtObject { property color backgroundColor: “#A5A5A5” property color backgroundColorAlt: “#818181” property color textColor: “#1E1E1E” }
  • 37. Changing Themes In top-level QML item (main.qml) Global variable accessible from everywhere in QML property alias g_theme: loader.item Loader { id: loader } Set theme on start-up Component.onCompleted: { loader.source = Qt.resolveUrl(“BlueTheme.qml”) } QQuickView forwards signal Connections { themeChanged(QString theme) target: g_viewer onThemeChanged: { loader.source = Qt.resolvedUrl(theme + “Theme.qml”) } }