Qt Quick 실용 가이드
이 페이지는 Qt Quick 에서 특정 작업을 수행하는 가장 간단하고 효과적인 방법을 보여주는, 쉽게 찾아볼 수 있는 유용한 참고 자료를 제공하기 위해 마련되었습니다. 각 해결책에는 해당되는 경우 QML 및/또는 C++ 코드 스니펫이 제공되며, 모든 스니펫은 정상적으로 작동하는지 확인하기 위해 Qt에 의해 자동으로 테스트됩니다.
다음과 같은 작업을 수행하려면:
- 버튼이 클릭되었을 때 QML에서 C++ 함수를 호출하려면
- 포커스가 활성화된 항목을 확인하려면
- Android의 TimePickerDialog와 같은 시간 선택기 만들기
- JavaScript에서 C++ 열거형(enum)을 사용하는 방법
- 게이지 만들기
버튼이 클릭되었을 때 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>
void Backend::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++ 열거형(enum) 사용하기
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)
{
}
bool Backend::load()
{
// 여기에서 로딩 작업을 수행합니다...
const QJSValue module = mEngine->importModule(":/script.mjs");
if (module.isError()) {
qWarning() << "Error loading script.mjs:" << module.toString();
return false;
}
const QJSValue function = module.property("backendStatusUpdate");
if (!function.isCallable()) {
qWarning() << "backendStatusUpdate script function is not callable!";
return false;
}
const QJSValue 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.

