Qt Quick 操作指南
本页面旨在提供一个易于查找且实用的参考指南,展示在Qt Quick 中执行特定任务的最简单、最佳方法。每种解决方案在适用时均提供QML和/或C++代码片段,且每个代码片段均由Qt自动测试,以确保其始终有效。
如何:
- 在按钮被点击时从 QML 调用 C++ 函数
- 查看哪个项目当前拥有焦点
- 创建一个类似 Android TimePickerDialog 的时间选择器
- 在 JavaScript 中使用 C++ 枚举
- 创建一个仪表
在按钮被点击时,从 QML 调用 C++ 函数
假设该 C++ 类型应在应用程序中的 QML 文件中全局可用,最简单的方法是使用QML_SINGLETON 将其设为 QML 单例。例如,在头文件backend.h 中:
#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>
voidBackend::doStuff()
{
qDebug() << "Did stuff!";
}然后,您可以在任何 QML 文件中调用该函数:
import QtQuick.Controls
import MyModule
ApplicationWindow {
width: 400
height: 400
title: qsTr("C++ Button example")
Button {
text: qsTr("Click me")
onClicked: Backend.doStuff()
}
}如果该 C++ 类型只需供一小部分 QML 文件使用,请考虑使用 `QML_ELEMENT`。有关将 C++ 类型暴露给 QML 的更多方法,请参阅《选择正确的 C++ 与 QML 集成方法》。
本示例假设Backend 类型可在某个QML模块中使用。在CMake中,这可通过qt_add_qml_module实现。有关详细演示的示例,请参阅《构建QML应用程序》。
查看哪个项目当前处于焦点状态
为窗口的activeFocusItem 属性编写属性变化信号处理程序:
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"
}
}
}这将把当前拥有活动焦点的项目输出到控制台。为了确保输出结果有实际意义,请为每个项目设置一个具有描述性的objectName 。
创建一个类似于 Android 的 TimePickerDialog 的时间选择器
我们准备了一个示例,其中包含几个QML 文件,用于演示如何实现这一点。您可以按照以下方式在您的应用程序中使用这些文件:
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!")
}
}
浅色主题下的 TimePickerDialog。 |
采用深色主题的 TimePickerDialog。 |
在 JavaScript 中使用 C++ 枚举
要将 C++ 枚举暴露给 JavaScript(即QJSEngine ,而非QQmlEngine 或QQmlApplicationEngine ),请使用newQMetaObject() 和registerModule():
QJSEngine engine;
engine.installExtensions(QJSEngine::AllExtensions);
QJSValue metaObjects = engine.newObject();
const QJSValue backendJsMetaObject = engine.newQMetaObject(&Backend::staticMetaObject);
metaObjects.setProperty("Backend", backendJsMetaObject);
// Repeat the two lines above for other types as needed.
engine.registerModule("MyApp", metaObjects);
Backend backend(&engine);
const bool loaded = backend.load();这样,该枚举即可在 JavaScript 中使用:
export function backendStatusUpdate(backendStatus) {
if (backendStatus === Backend.Error) {
console.warn("Error!")
return
}
console.log("Backend loaded successfully")
}在使用 `QQmlEngine ` 或 `QQmlApplicationEngine` 时,还有更简便的选择;更多信息请参阅《选择 C++ 与 QML 之间的正确集成方法》。
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)
{
}
boolBackend::load()
{
// 在此处执行加载操作...
constQJSValue module= mEngine->importModule(":/script.mjs");
if(module.isError()) {
qWarning() << "Error loading script.mjs:" << module.toString();
return false;
}
constQJSValue function=module.property("backendStatusUpdate");
if(!function.isCallable()) {
qWarning() << "backendStatusUpdate script function is not callable!";
return false;
}
constQJSValue functionResult=function.call(QJSValueList()<<Loaded);
if(functionResult.isError()) {
qWarning() << "backendStatusUpdate script function had errors:" << functionResult.toString();
return false;
}
return true;
}有关更多信息,请参阅QObject Integration 。
创建一个仪表
我们准备了一个示例,其中包含几个C++ 和 QML 文件,用于演示如何实现此功能。您可以按照以下方式在您的应用程序中使用它们:
import QtQuick.Controls
import GaugeHowTo
ApplicationWindow {
width: 400
height: 400
title: qsTr("Gauge example")
Gauge {
minimumValue: 0
value: 75
maximumValue: 100
}
}
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.

