Qt Quick How-tos▲
This page aims to provide an easily discoverable, useful reference that shows the simplest and best way of performing specific tasks in Qt Quick. Each solution provides QML and/or C++ code snippets where applicable, and every snippet is automatically tested by Qt to ensure they remain functional.
How do I:
Call a C++ function from QML when a Button is clicked▲
#include <QObject>
#include <QQmlEngine>
class
Backend : public
QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public
:
Q_INVOKABLE void
doStuff();
}
;
backend.cpp:
#include
"backend.h"
#include <QDebug>
void
Backend::
doStuff()
{
qDebug() &
lt;&
lt; "Did stuff!"
;
}
You can then call that function from any QML file:
import
QtQuick.Controls
import
MyModule
ApplicationWindow
{
width
:
400
height
:
400
title
:
qsTr("C++ Button example"
)
Button
{
text
:
qsTr("Click me"
)
onClicked
:
Backend.doStuff()
}
}
If the C++ type only needs to be available to a small set of QML files, consider using QML_ELEMENT. For more ways of exposing C++ types to QML, see Choosing the Correct Integration Method Between C++ and QML.
This example assumes that the Backend type is available in a QML module. With CMake, this is done via qt_add_qml_module. For an example that demonstrates this in detail, see Building a QML application.
See which item has active focus▲
Write a property change signal handler for the window's activeFocusItem property:
import
QtQuick
import
QtQuick.Controls
ApplicationWindow
{
width
:
400
height
:
400
visible
:
true
title
:
qsTr("Active focus debugging example"
)
onActiveFocusItemChanged
:
print("activeFocusItem: "
+
activeFocusItem)
Row
{
TextField
{
objectName
:
"textField1"
}
TextField
{
objectName
:
"textField2"
}
}
}
This will print the item which currently has active focus to the console. To ensure that the output is useful, give each item a descriptive objectName.
Create a time picker like Android's TimePickerDialog▲
We've prepared an example that consists of a few QML files which demonstrate how to do this. They can be used in your application in the following manner:
import
QtQuick
import
QtQuick.Layouts
import
QtQuick.Controls.Material
ApplicationWindow
{
id
:
window
width
:
600
height
:
600
visible
:
true
title
:
qsTr("Time Picker Example"
)
Material.theme
:
darkThemeSwitch.checked ? Material.Dark :
Material.Light
// Shows the selected time and opens the dialog.
TimeComponentLabel {
id
:
openDialogLabel
width
:
parent.width -
80
anchors.centerIn
:
parent
font.pixelSize
:
Qt.application.font.pixelSize *
8
renderTypeQuality
:
Text.VeryHighRenderTypeQuality
interactive
:
!
timePickerDialog.opened
text
:
Qt.formatTime(new Date
(1970
, 1
, 1
, timePickerDialog.hours, timePickerDialog.minutes), "hh:mm"
)
onTapped
:
timePickerDialog.openWithMode(TimePicker.Mode.Hours)
}
ColumnLayout
{
// We always want the openDialogLabel to be centered in the window, not us.
// For that reason, we use anchors rather than putting the root items into a ColumnLayout.
anchors.horizontalCenter
:
parent.horizontalCenter
anchors.top
:
openDialogLabel.bottom
anchors.topMargin
:
24
spacing
:
12
Switch
{
id
:
is24HourSwitch
text
:
qsTr("24 Hour"
)
checked
:
timePickerDialog.is24Hour
}
Switch
{
id
:
darkThemeSwitch
text
:
qsTr("Dark"
)
}
}
TimePickerDialog {
id
:
timePickerDialog
anchors.centerIn
:
parent
is24Hour
:
is24HourSwitch.checked
onTimeAccepted
:
print("A time was chosen - do something here!"
)
}
}
Use a C++ enum in JavaScript▲
To expose a C++ enum to JavaScript (that is, QJSEngine, not QQmlEngine or QQmlApplicationEngine), use QJSEngine::newQMetaObject():
QJSEngine engine;
engine.installExtensions(QJSEngine::
AllExtensions);
QJSValue backendJsMetaObject =
engine.newQMetaObject(&
amp;Backend::
staticMetaObject);
engine.globalObject().setProperty("Backend"
, backendJsMetaObject);
Backend backend(&
amp;engine);
const
bool
loaded =
backend.load();
The enum can then be used from JavaScript:
export
function backendStatusUpdate(backendStatus) {
if
(backendStatus ===
Backend.Error) {
console.warn("Error!"
)
return
}
console.log("Backend loaded successfully"
)
}
When using QQmlEngine or QQmlApplicationEngine, there are easier options; see Choosing the Correct Integration Method Between C++ and QML for more information.
backend.h:
#include <QObject>
#include <QJSEngine>
class
Backend : public
QObject
{
Q_OBJECT
public
:
Backend(QJSEngine *
engine);
enum
Status {
Unknown,
Error,
Loading,
Loaded
}
;
Q_ENUM(Status)
bool
load();
private
:
QJSEngine *
mEngine =
nullptr
;
}
;
backend.cpp:
#include
"backend.h"
Backend::
Backend(QJSEngine *
engine) :
mEngine(engine)
{
}
bool
Backend::
load()
{
// Do some loading here...
const
QJSValue module
=
mEngine-&
gt;import
Module(":/script.mjs"
);
if
(module
.isError()) {
qWarning() &
lt;&
lt; "Error loading script.mjs:"
&
lt;&
lt; module
.toString();
return
false
;
}
const
QJSValue function =
module
.property("backendStatusUpdate"
);
if
(!
function.isCallable()) {
qWarning() &
lt;&
lt; "backendStatusUpdate script function is not callable!"
;
return
false
;
}
const
QJSValue functionResult =
function.call(QJSValueList() &
lt;&
lt; Loaded);
if
(functionResult.isError()) {
qWarning() &
lt;&
lt; "backendStatusUpdate script function had errors:"
&
lt;&
lt; functionResult.toString();
return
false
;
}
return
true
;
}
For more information, see QObject Integration.