SlideShare a Scribd company logo
1 of 38
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 multi threads
Qt multi threadsQt multi threads
Qt multi threadsYnon Perek
 
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IBest Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IICS
 
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)DataWorks Summit
 
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 4ICS
 
Qt for beginners part 1 overview and key concepts
Qt for beginners part 1   overview and key conceptsQt for beginners part 1   overview and key concepts
Qt for beginners part 1 overview and key conceptsICS
 
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.7Pasi Kellokoski
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programmingICS
 
Scripting Your Qt Application
Scripting Your Qt ApplicationScripting Your Qt Application
Scripting Your Qt Applicationaccount inactive
 
Introduction to QML
Introduction to QMLIntroduction to QML
Introduction to QMLAlan Uthoff
 
Qt Framework Events Signals Threads
Qt Framework Events Signals ThreadsQt Framework Events Signals Threads
Qt Framework Events Signals ThreadsNeera Mital
 
Intro to Helm for Kubernetes
Intro to Helm for KubernetesIntro to Helm for Kubernetes
Intro to Helm for KubernetesCarlos E. Salazar
 
Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion...
 Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion... Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion...
Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion...Codemotion
 
Kubernetes - A Comprehensive Overview
Kubernetes - A Comprehensive OverviewKubernetes - A Comprehensive Overview
Kubernetes - A Comprehensive OverviewBob Killen
 

What's hot (20)

Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Test driving QML
Test driving QMLTest driving QML
Test driving QML
 
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IBest Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part I
 
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 Workshop
Qt WorkshopQt Workshop
Qt Workshop
 
Hello, QML
Hello, QMLHello, QML
Hello, QML
 
Qt programming-using-cpp
Qt programming-using-cppQt programming-using-cpp
Qt programming-using-cpp
 
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
 
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 for beginners part 1 overview and key concepts
Qt for beginners part 1   overview and key conceptsQt for beginners part 1   overview and key concepts
Qt for beginners part 1 overview and key concepts
 
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
 
02 - Basics of Qt
02 - Basics of Qt02 - Basics of Qt
02 - Basics of Qt
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programming
 
Scripting Your Qt Application
Scripting Your Qt ApplicationScripting Your Qt Application
Scripting Your Qt Application
 
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
 
Introduction to QML
Introduction to QMLIntroduction to QML
Introduction to QML
 
Qt Framework Events Signals Threads
Qt Framework Events Signals ThreadsQt Framework Events Signals Threads
Qt Framework Events Signals Threads
 
Intro to Helm for Kubernetes
Intro to Helm for KubernetesIntro to Helm for Kubernetes
Intro to Helm for Kubernetes
 
Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion...
 Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion... Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion...
Helm - the Better Way to Deploy on Kubernetes - Reinhard Nägele - Codemotion...
 
Kubernetes - A Comprehensive Overview
Kubernetes - A Comprehensive OverviewKubernetes - A Comprehensive Overview
Kubernetes - A Comprehensive Overview
 

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 modelingCodemotion
 
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 modelingMario Fusco
 
06 win forms
06 win forms06 win forms
06 win formsmrjw
 
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.15Rajes Wari
 
Practicalfileofvb workshop
Practicalfileofvb workshopPracticalfileofvb workshop
Practicalfileofvb workshopdhi her
 
engineeringdsgtnotesofunitfivesnists.ppt
engineeringdsgtnotesofunitfivesnists.pptengineeringdsgtnotesofunitfivesnists.ppt
engineeringdsgtnotesofunitfivesnists.pptsharanyak0721
 
intro_gui
intro_guiintro_gui
intro_guifilipb2
 
Csphtp1 12
Csphtp1 12Csphtp1 12
Csphtp1 12HUST
 
Flutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfFlutter State Management Using GetX.pdf
Flutter State Management Using GetX.pdfKaty Slemon
 
MEngine Advanced
MEngine AdvancedMEngine Advanced
MEngine Advancedeuming
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptWalid 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 possibleQuickBird Studios GmbH
 

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 DockerBurkhard 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 OwnershipBurkhard Stubert
 
Burkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert: Project Portfolio and ExpertiseBurkhard Stubert: Project Portfolio and Expertise
Burkhard Stubert: Project Portfolio and ExpertiseBurkhard 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 QtBurkhard 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

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 

Recently uploaded (20)

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 

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”) } }