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> 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ファイルからなるサンプルを用意しました。これらの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!") } }
Light テーマの TimePickerDialog。 | ダークテーマのTimePickerDialog。 |
JavaScriptでC++列挙型を使用する
C++の列挙型をJavaScriptに公開するには(つまり、QQmlEngine やQQmlApplicationEngine ではなく、QJSEngine )、QJSEngine::newQMetaObject ()を使用します:
QJSEngine engine; engine.installExtensions(QJSEngine::AllExtensions); QJSValue backendJsMetaObject = engine.newQMetaObject(&Backend::staticMetaObject); engine.globalObject().setProperty("Backend", backendJsMetaObject); 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() { // Do some loading here... 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 を参照してください。
2024The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。