QMLの基礎 - QMLとC++のバインディング
ナビゲーションに移動
検索に移動
概要
QMLとC++のバインディング手順を記載する。
ここでは、Qt Creatorにおいて、Qt Quickの空のプロジェクトを作成した時に自動生成されるソースコードを元にする。
QMLからC++へアクセスする (推奨)
setContextProperty
メソッドにQObject
のインスタンスを渡して、QMLからC++のクラスメソッドを呼んでいる。
// main.cppファイル
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "CMainWindow.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl)
{
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
// 追加
CMainWindow MainWindow;
engine.rootContext()->setContextProperty("MainWindow", &MainWindow);
// 複数のクラスを追加する場合、以下のように記述する
//CSubWindow SubWindow;
//engine.rootContext()->setContextProperty("SubWindow", &SubWindow);
return app.exec();
}
// CMainWindow.hファイル
#pragma once
#include <QObject>
#include <QString>
class CMainWindow : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QString getTextFromCpp()
{
return QString("This is the text from C++");
}
};
// main.qmlファイル
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
// 追加
Text {
id: textMainMessage
text: qsTr("ここにテキストが表示される")
x: (parent.width / 2) - width / 2
y: (parent.height / 2) - height / 2
Layout.fillWidth: true
Layout.fillHeight: true
font.pixelSize: 15
color: "#ffffff"
}
Button {
id: mainWindowButton
x: (parent.width / 2) - width / 2
y: (parent.height / 2) + height / 2
width: 120
height: 35
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
text: qsTr("OK")
Connections {
target: mainWindowButton
function onClicked() {
let strMainMessage = MainWindow.getTextFromCpp(); // C++のメソッドを呼ぶ
textMainMessage.text = strMainMessage;
}
}
}
}
C++からQMLオブジェクトへアクセスする (非推奨)
C++からQMLオブジェクトへのアクセスは、C++とQMLの独立性の観点から非推奨であることに注意する。
ここでは、objectNameでアクセスする方法を記載する。(他にも様々な手順がある)
まず、root要素へアクセスして、子要素であるText
へQMLで定義するobjectName
でアクセスする。
// main.cppファイル
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "CMainWindow.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl)
{
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
// 追加
// ルートオブジェクトおよびmain.qmlに定義されているobjectName(textObject)のQMLオブジェクトへのアクセスを取得する
QObject *rootObject = engine.rootObjects().first();
QObject *qmlObject = rootObject->findChild<QObject*>("textObject");
// QMLオブジェクトに対して、任意の値を設定する
qmlObject->setProperty("text", "Text from C++");
return app.exec();
}
次に、QML側では、アクセスする子要素にobjectName
を定義する。
// main.qmlファイル
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
// 追加
Text {
id: textMainMessage
objectName: "textObject"
text: qsTr("ここにテキストが表示される")
x: (parent.width / 2) - width / 2
y: (parent.height / 2) - height / 2
Layout.fillWidth: true
Layout.fillHeight: true
font.pixelSize: 15
color: "#ffffff"
}
}