C++ を使用した QML 拡張機能の作成
この Qt Qml モジュールは、C++ 拡張機能を通じて QML を拡張するための一連の API を提供します。拡張機能を作成することで、独自の QML 型を追加したり、既存の Qt 型を拡張したり、通常の QML コードからはアクセスできない C/C++ 関数を呼び出したりすることができます。
このチュートリアルでは、プロパティ、シグナル、バインディングといった QML の主要な機能を含む、C++ を使用した QML 拡張機能の作成方法を解説します。また、プラグインを通じて拡張機能を展開する方法についても説明します。
このチュートリアルで取り上げられているトピックの多くは、「概要 - QML と C++ の統合」およびそのドキュメントのサブトピックでさらに詳しく説明されています。特に、「C++ クラスの属性を QML に公開する」および「C++ から QML 型を定義する」というサブトピックが参考になるでしょう。
チュートリアルのソースを開く
このチュートリアルのコードは、Qtのソースコードの一部として利用可能です。Qt Online Installer でQtをインストールした場合は、Qtのインストールディレクトリ内のExamples/Qt-6.12.0/qml/tutorials/extending-qml/にソースコードがあります。
プロジェクトをゼロから作成する
あるいは、ソースをゼロから作成してチュートリアルを進めることもできます。各章ごとに、「Qt Quick 」の「Application」テンプレートを使用して新しいプロジェクトを作成してください。
- Qt Creator を使用する場合は、Qt Creator: CreateQt Quick Applications の指示に従ってください。
- Qt Extension for Visual Studio Code を使用する場合は、Qt Extension for Visual Studio Code :Qtプロジェクトの作成に記載されている手順に従ってください。
その場合は、xml-ph-0001@deepl.internal: Create xml-ph-0002@deepl.internal Applications の指示に従って xml-ph-0000@deepl.internal を使用してください。
第 1 章: 新しいタイプの作成
extending-qml/chapter1-basics
QML を拡張する際の一般的な作業として、組み込みの機能を超えるカスタム機能をサポートする新しい QML 型を提供することが挙げられます Qt Quick types。たとえば、特定のデータモデルを実装したり、カスタムペインティングや描画機能を備えた型を提供したり、組み込みの QML 機能では利用できないネットワークプログラミングなどのシステム機能にアクセスしたりするために、これを行うことができます。
このチュートリアルでは、Qt Quick モジュール内のC++クラスを使用してQMLを拡張する方法を紹介します。最終的には、バインディングやシグナルといったQMLの機能を通じて相互に接続された、いくつかのカスタムQML型によって実装され、プラグインを通じてQML Runtimeで利用可能になる、シンプルな円グラフ表示が完成します。
まず、「PieChart」という名前の新しいQML型を作成しましょう。この型には、nameとcolorという2つのプロパティがあります。これを「Charts」というインポート可能な型ネームスペースに、バージョン1.0として登録します。
このPieChart 型を、QMLから次のように使用できるようにします:
import Charts
PieChart {
width: 100; height: 100
name: "A simple pie chart"
color: "red"
}注: Qt Creator がPieChart を正しくハイライト表示するには、QML Language Server とそのセマンティックハイライトを有効にする必要がある場合があります ( Qt Creatorまたは Qt Extension for Visual Studio Code で設定)。
これを行うには、このPieChart 型とそのプロパティをカプセル化する C++ クラスが必要です。QML は Qtのメタオブジェクトシステムを多用しているため、この新しいクラスは以下の要件を満たす必要があります:
- 以下から継承することQObject
- Q_PROPERTY マクロを使用してプロパティを宣言すること
クラスの宣言
以下は、piechart.h に定義されたPieChart クラスです:
#include <QtQuick/QQuickPaintedItem>
#include <QColor>
class PieChart : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName FINAL)
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
QML_ELEMENT
public:
PieChart(QQuickItem *parent = nullptr);
QString name() const;
void setName(const QString &name);
QColor color() const;
void setColor(const QColor &color);
void paint(QPainter *painter) override;
private:
QString m_name;
QColor m_color;
};このクラスがQQuickPaintedItem を継承しているのは、QQuickPaintedItem::paint()をオーバーライドして、QPainter API による描画操作を実行したいからです。もしこのクラスが単なるデータ型を表すだけで、実際に表示する必要のあるアイテムではない場合は、QObject を継承するだけで済みます。あるいは、既存のQObject ベースのクラスの機能を拡張したい場合は、そのクラスを継承することもできます。 あるいは、QPainter API による描画操作を必要としない視覚的アイテムを作成したい場合は、単にQQuickItem をサブクラス化すればよい。
PieChart クラスは、Q_PROPERTY マクロを使用してname とcolor の2つのプロパティを定義し、QQuickPaintedItem::paint()をオーバーライドしています。PieChart クラスは、QMLから使用できるようにするためにQML_ELEMENT マクロを使用して登録されます。クラスを登録しない場合、App.qml はPieChart を作成できません。
qmakeの設定
登録を有効にするには、プロジェクトファイルのCONFIG にqmltypes オプションを追加し、QML_IMPORT_NAME およびQML_IMPORT_MAJOR_VERSION を指定する必要があります:
CONFIG += qmltypes
QML_IMPORT_NAME = Charts
QML_IMPORT_MAJOR_VERSION = 1さらに、QMLモジュールを作成するには、qmldirファイルを手動で追加する必要があります。
module Charts
typeinfo chapter1-basics.qmltypes
depends QtQuick
prefer :/qt/qml/Charts/
App 254.0 App.qmlCMakeの設定
CMake を使用する際、登録を有効にするには、qt_add_qml_module()コマンドを使用します:
qt_add_qml_module(chapter1-basics
URI Charts
QML_FILES App.qml
DEPENDENCIES QtQuick
)qt_add_qml_module()API は、QML モジュール用のqmldir ファイルを自動的に生成します。
クラスの実装
piechart.cpp 内のクラス実装では、m_name およびm_color の値を適宜設定・返すとともに、paint() を実装して簡単な円グラフを描画します:
PieChart::PieChart(QQuickItem *parent)
: QQuickPaintedItem(parent)
{
}
...
void PieChart::paint(QPainter *painter)
{
QPen pen(m_color, 2);
painter->setPen(pen);
painter->setRenderHints(QPainter::Antialiasing, true);
painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16);
}QMLでの使用方法
PieChart 型を定義したので、QMLからこれを使用します。App.qml ファイルでは、PieChart アイテムを作成し、標準のQMLText アイテムを使用して円グラフの詳細を表示します:
import Charts
import QtQuick
Item {
width: 300; height: 200
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
name: "A simple pie chart"
color: "red"
}
Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: aPieChart.name
}
}QML では色が文字列として指定されていますが、PieChart のcolor プロパティに対しては自動的にQColor オブジェクトに変換される点に注意してください。このほかにも、さまざまな値型に対して自動変換が提供されています。たとえば、「640x480」のような文字列は、自動的にQSize 値に変換されます。
また、QQuickView を使用してApp.qml を実行・表示する C++ アプリケーションも作成します。
以下に、main.cpp を使用したアプリケーションを示します:
#include "piechart.h"
#include <QtQuick/QQuickView>
#include <QGuiApplication>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.loadFromModule("Charts", "App");
view.show();
return QGuiApplication::exec();
}プロジェクトのビルド
プロジェクトをビルドするには、ファイルをインクルードし、ライブラリに対してリンクを行い、QMLに公開されるすべての型に対してバージョン1.0の「Charts」という名前空間を定義します。
qmake を使用する場合:
QT += qml quick
CONFIG += qmltypes
QML_IMPORT_NAME = Charts
QML_IMPORT_MAJOR_VERSION = 1
HEADERS += piechart.h
SOURCES += piechart.cpp \
main.cpp
RESOURCES += chapter1-basics.qrc
DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter1-basics
target.path = $$DESTPATH
INSTALLS += targetCMake を使用する場合:
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(chapter1-basics LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick)
qt_standard_project_setup(REQUIRES 6.8)
qt_add_executable(chapter1-basics
main.cpp
piechart.cpp piechart.h
)
set_target_properties(chapter1-basics PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(chapter1-basics PUBLIC
Qt6::Core
Qt6::Gui
Qt6::Qml
Qt6::Quick
)
qt_add_qml_module(chapter1-basics
URI Charts
QML_FILES App.qml
DEPENDENCIES QtQuick
)
install(TARGETS chapter1-basics
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
qt_generate_deploy_qml_app_script(
TARGET chapter1-basics
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
)
install(SCRIPT ${deploy_script})これでアプリケーションをビルドして実行できます:

注: 「Expression ... depends on non-bindable properties: PieChart::name」という警告が表示される場合があります。 これは、書き込み可能なname プロパティへのバインディングを追加したものの、そのプロパティに対するnotifyシグナルをまだ定義していないためです。そのため、name の値が変更されても、QMLエンジンはバインディングを更新できません。この問題については、以降の章で対処します。
第2章:C++のメソッドおよびシグナルへの接続
extending-qml/chapter2-methods
PieChart クラスに、チャートを消去した後、「chartCleared」シグナルを発行する「clearChart()」メソッドを実装するとします。この場合、App.qml クラスは次のように、clearChart() を呼び出し、chartCleared() シグナルを受信できるようになります:
import Charts
import QtQuick
Item {
width: 300; height: 200
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red"
onChartCleared: console.log("The chart has been cleared")
}
MouseArea {
anchors.fill: parent
onClicked: aPieChart.clearChart()
}
Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to clear the chart"
}
}
これを行うために、C++クラスにclearChart() メソッドとchartCleared() シグナルを追加します:
class PieChart : public QQuickPaintedItem
{
...
public:
...
Q_INVOKABLE void clearChart();
signals:
void chartCleared();
...
};Q_INVOKABLE を使用することで、clearChart() メソッドがQtメタオブジェクトシステムから利用可能になり、ひいてはQMLからも利用できるようになります。
注: `Q_INVOKABLE` を使用する代わりに、メソッドを Qt スロットとして宣言することも可能です 。これは、public および protected スロットは QML からも呼び出せるためです(private スロットは呼び出せません)。
clearChart() メソッドは、色をQt::transparent に変更し、チャートを再描画した後、chartCleared() シグナルを発行します。
ここで、アプリケーションを実行してウィンドウをクリックすると、円グラフが消え、アプリケーションから次のような出力が表示されます:
qml: The chart has been cleared第3章:プロパティバインディングの追加
extending-qml/chapter3-bindings
プロパティバインディングは、QMLの強力な機能の一つであり、異なる型の値を自動的に同期させることができます。これは、プロパティの値が変更された際に、シグナルを使用して他の型の値に通知し、更新します。
color プロパティに対してプロパティバインディングを有効にしてみましょう。つまり、次のようなコードがある場合:
import Charts
import QtQuick
Item {
width: 300; height: 200
Row {
anchors.centerIn: parent
spacing: 20
PieChart {
id: chartA
width: 100; height: 100
color: "red"
}
PieChart {
id: chartB
width: 100; height: 100
color: chartA.color
}
}
MouseArea {
anchors.fill: parent
onClicked: { chartA.color = "blue" }
}
Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to change the chart color"
}
}
「color: chartA.color」という記述は、chartB のcolor 値を、chartA のcolor にバインドします。chartA のcolor 値が変更されるたびに、chartB のcolor 値が同じ値に更新されます。ウィンドウがクリックされると、MouseArea 内のonClicked ハンドラがchartA の色を変更し、それによって両方のチャートが青色に変わります。
color プロパティのプロパティバインディングを有効にするのは簡単です。値が変更されるたびに「colorChanged」シグナルが発信されることを示すため、そのQ_PROPERTY() 宣言にNOTIFY機能を追加します。
class PieChart : public QQuickPaintedItem
{
...
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL)
public:
...
signals:
void colorChanged();
...
};次に、setColor() 内でこのシグナルを発行します:
void PieChart::setColor(const QColor &color)
{
if (color != m_color) {
m_color = color;
update(); // repaint with the new color
emit colorChanged();
}
}setColor() では、colorChanged() を発行する前に、色の値が実際に変更されたかどうかを確認することが重要です。これにより、シグナルが不必要に発行されるのを防ぎ、他のタイプが値の変更に応答した際にループが発生するのを防ぐことができます。
バインディングの使用はQMLにおいて不可欠です。プロパティが実装可能な場合は、常にNOTIFYシグナルを追加し、そのプロパティをバインディングで使用できるようにすべきです。 バインディングできないプロパティは自動的に更新されず、QML内で柔軟に利用することができません。また、QMLの使用においてはバインディングが頻繁に呼び出され、その機能に依存しているため、バインディングが実装されていない場合、カスタムQML型を使用するユーザーは予期しない動作に遭遇する可能性があります。
第4章:カスタムプロパティ型の使用
extending-qml/chapter4-customPropertyTypes
PieChart 型には現在、文字列型のプロパティと色型のプロパティがあります。他にも多くの種類のプロパティを持つことが可能です。例えば、各チャートの識別子を格納するためのint型のプロパティを持つこともできます:
// C++
class PieChart : public QQuickPaintedItem
{
Q_PROPERTY(int chartId READ chartId WRITE setChartId NOTIFY chartIdChanged)
...
public:
void setChartId(int chartId);
int chartId() const;
...
signals:
void chartIdChanged();
};
// QML
PieChart {
...
chartId: 100
}int 以外にも、さまざまなプロパティ型を使用できます。QColor 、QSize 、QRect など、多くのQtデータ型はQMLで自動的にサポートされています。(完全なリストについては、「QMLとC++間のデータ型変換」のドキュメントを参照してください。)
QMLがデフォルトでサポートしていない型のプロパティを作成したい場合は、その型をQMLエンジンに登録する必要があります。
例えば、property の使用を、color プロパティを持つ「PieSlice」という型に置き換えてみましょう。色を割り当てる代わりに、それ自体がcolor を含むPieSlice 値を割り当てます:
import Charts
import QtQuick
Item {
width: 300; height: 200
PieChart {
id: chart
anchors.centerIn: parent
width: 100; height: 100
pieSlice: PieSlice {
anchors.fill: parent
color: "red"
}
}
Component.onCompleted: console.log("The pie is colored " + chart.pieSlice.color)
}PieChart と同様に、この新しいPieSlice 型はQQuickPaintedItem を継承し、Q_PROPERTY()を用いてプロパティを宣言しています:
class PieSlice : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
QML_ELEMENT
public:
PieSlice(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(const QColor &color);
void paint(QPainter *painter) override;
private:
QColor m_color;
};PieChart 内でこれを使用するには、color のプロパティ宣言と関連するメソッドのシグネチャを次のように変更します:
class PieChart : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice FINAL)
...
public:
...
PieSlice *pieSlice() const;
void setPieSlice(PieSlice *pieSlice);
...
};setPieSlice() を実装する際に注意すべき点が1つあります。PieSlice はビジュアルアイテムであるため、QQuickItem::setParentItem()を使用してPieChart の子として設定する必要があります。これにより、PieChart はコンテンツが描画される際にこの子アイテムを描画するよう認識します:
void PieChart::setPieSlice(PieSlice *pieSlice)
{
m_pieSlice = pieSlice;
pieSlice->setParentItem(this);
}PieChart 型と同様に、PieSlice 型もQML_ELEMENT を使用してQMLにエクスポートする必要があります。
class PieSlice : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
QML_ELEMENT
public:
PieSlice(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(const QColor &color);
void paint(QPainter *painter) override;
private:
QColor m_color;
};
...PieChart と同様に、ビルドファイルに「Charts」タイプネームスペース(バージョン 1.0)を追加します:
qmake を使用する場合:
QT += qml quick
CONFIG += qmltypes
QML_IMPORT_NAME = Charts
QML_IMPORT_MAJOR_VERSION = 1
HEADERS += piechart.h \
pieslice.h
SOURCES += piechart.cpp \
pieslice.cpp \
main.cpp
RESOURCES += chapter4-customPropertyTypes.qrc
DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter4-customPropertyTypes
target.path = $$DESTPATH
INSTALLS += targetCMakeを使用する場合:
...
qt_add_executable(chapter4-customPropertyTypes
main.cpp
piechart.cpp piechart.h
pieslice.cpp pieslice.h
)
qt_add_qml_module(chapter4-customPropertyTypes
URI Charts
QML_FILES App.qml
DEPENDENCIES QtQuick
)
...第5章: リストプロパティ型の使用
extending-qml/chapter5-listproperties
現在、PieChart にはPieSlice を1つしか持つことができません。理想的には、チャートには色やサイズが異なる複数のスライスが含まれるべきです。これを実現するために、PieSlice 項目のリストを受け入れるslices プロパティを用意することができます:
pragma ComponentBehavior: Bound
import Charts
import QtQuick
Item {
width: 300; height: 200
PieChart {
id: chart
anchors.centerIn: parent
width: 100; height: 100
component Slice: PieSlice {
parent: chart
anchors.fill: parent
}
slices: [
Slice {
color: "red"
fromAngle: 0
angleSpan: 110
},
Slice {
color: "black"
fromAngle: 110
angleSpan: 50
},
Slice {
color: "blue"
fromAngle: 160
angleSpan: 100
}
]
}
}
これを行うには、PieChart 内のpieSlice プロパティを、QQmlListProperty 型として宣言されたslices プロパティに置き換えます。QQmlListProperty クラスを使用すると、QML に公開される型にリストプロパティを作成できます。pieSlice() 関数を、スライスのリストを返すslices() 関数に置き換えます。また、QList を使用して、内部のスライスリストをm_slices として格納します:
class PieChart : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<PieSlice> slices READ slices FINAL)
...
public:
...
QQmlListProperty<PieSlice> slices();
private:
QString m_name;
QList<PieSlice *> m_slices;
};slices プロパティには対応するWRITE 関数がありませんが、QQmlListProperty の動作の仕組みにより、依然として変更可能です。PieChart の実装では、PieChart::slices() を実装してQQmlListProperty 値を返すようにします:
QQmlListProperty<PieSlice> PieChart::slices()
{
return QQmlListProperty<PieSlice>(this, &m_slices);
}これにより、QMLからリストを操作するために必要な関数が生成されます。結果として得られるQQmlListProperty は、リストへのビューとなります。あるいは、リストへの個々のアクセス関数を手動で用意することも可能です。これは、リストがQList ではない場合や、リストへのQMLからのアクセスを制限またはカスタマイズしたい場合に必要です。 ただし、ほとんどの場合、QList ポインタを受け取るコンストラクタを使用するのが最も安全かつ簡単な選択肢です。
また、PieSlice クラスも変更され、fromAngle およびangleSpan プロパティが追加され、これらの値に基づいてスライスが描画されるようになりました。このチュートリアルの前のページを読んでいる方であれば、これは単純な変更であるため、ここではコードは掲載しません。
第6章:拡張プラグインの作成
extending-qml/chapter6-plugins
現在、PieChart およびPieSlice 型はApp.qml によって使用されており、C++ アプリケーション内のQQuickView を使用して表示されます。 QML拡張機能を利用する別の方法として、プラグインライブラリを作成し、QMLエンジンに対して新しいQMLインポートモジュールとして提供する方法があります。これにより、PieChart およびPieSlice といった型を、特定のアプリケーションでのみ使用するように制限するのではなく、任意のQMLアプリケーションからインポート可能な型ネームスペースに登録できるようになります。
プラグインの作成手順については、「QML用C++プラグインの作成」で説明されています。まず、ChartsPlugin という名前のプラグインクラスを作成します。このクラスはQQmlEngineExtensionPlugin をサブクラス化し、Q_PLUGIN_METADATA()マクロを使用して、Qtメタオブジェクトシステムにプラグインを登録します。
以下は、chartsplugin.h 内のChartsPlugin の定義です。
#include <QQmlEngineExtensionPlugin>
class ChartsPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
};次に、ビルドファイルを設定して、プロジェクトをプラグインライブラリとして定義します。
qmake を使用する場合:
TEMPLATE = lib
CONFIG += plugin qmltypes
QT += qml quick
QML_IMPORT_NAME = Charts
QML_IMPORT_MAJOR_VERSION = 1
TARGET = $$qtLibraryTarget(chartsplugin)
HEADERS += piechart.h \
pieslice.h \
chartsplugin.h
SOURCES += piechart.cpp \
pieslice.cpp
DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter6-plugins/$$QML_IMPORT_NAME
target.path=$$DESTPATH
qmldir.files=$$PWD/qmldir
qmldir.path=$$DESTPATH
INSTALLS += target qmldir
CONFIG += install_ok # Do not cargo-cult this!
OTHER_FILES += qmldir
# Copy the qmldir file to the same folder as the plugin binary
cpqmldir.files = qmldir
cpqmldir.path = .
COPIES += cpqmldirCMakeを使用する場合:
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
qt6_policy(SET QTP0001 NEW)
qt6_add_qml_module(chartsplugin
URI "Charts"
PLUGIN_TARGET chartsplugin
DEPENDENCIES QtQuick
)
target_sources(chartsplugin PRIVATE
piechart.cpp piechart.h
pieslice.cpp pieslice.h
)
target_link_libraries(chartsplugin PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Qml
Qt6::Quick
)
install(TARGETS chartsplugin
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}/Charts"
LIBRARY DESTINATION "${CMAKE_INSTALL_BINDIR}/Charts"
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir
DESTINATION "${CMAKE_INSTALL_BINDIR}/Charts"
)Windows または Linux でこの例をビルドする場合、Charts ディレクトリは、新しいインポートモジュールを使用するアプリケーションと同じ階層に配置されます。これにより、QML インポートのデフォルト検索パスにはアプリケーション実行ファイルのディレクトリが含まれるため、QML エンジンは当モジュールを検出できるようになります。 macOSでは、プラグインバイナリはアプリケーションバンドル内のContents/PlugIns にコピーされます。qmakeを使用する場合、このパスはchapter6-plugins/app.pro で設定されます:
macos:!qtConfig(static) {
charts.files = $$OUT_PWD/Charts
charts.path = Contents/PlugIns
QMAKE_BUNDLE_DATA += charts
}これに対応するため、main.cpp にもこの場所をQML インポートパスとして追加する必要があります:
QQuickView view;
...カスタムインポートパスを定義することは、同じ QML インポートを使用するアプリケーションが複数ある場合にも役立ちます。
また、.pro ファイルには、モジュール定義のqmldirファイルが常にプラグインバイナリと同じ場所にコピーされるようにするための追加の処理が含まれています。
qmldir ファイルでは、モジュール名と、そのモジュールによって利用可能になるプラグインを宣言します:
module Charts
optional plugin chartsplugin
typeinfo plugins.qmltypes
depends QtQuick
prefer :/qt/qml/Charts/これで、QMLエンジンがその場所を認識していれば、どのアプリケーションにもインポート可能なQMLモジュールが完成しました。この例には、App.qml を読み込む実行ファイルが含まれており、そこではimport Charts 1.0 文が使用されています。あるいは、qmlツールを使用してQMLファイルを読み込み、qmldir ファイルが見つかるようにインポートパスを現在のディレクトリに設定することもできます:
qml -I . App.qml「Charts」モジュールは QML エンジンによって読み込まれ、そのモジュールが提供する型は、それをインポートする任意の QML ドキュメントで使用可能になります。
第7章:まとめ
このチュートリアルでは、QML拡張機能を作成するための基本的な手順を説明しました:
- QObject をサブクラス化して新しいQML型を定義し、QML_ELEMENT またはQML_NAMED_ELEMENT()で登録する
- Q_INVOKABLE またはQtスロットを使用して呼び出し可能なメソッドを追加し、
onSignal構文でQtシグナルに接続する - NOTIFYシグナルを定義してプロパティバインディングを追加します
- 組み込みの型では不十分な場合は、カスタムプロパティ型を定義します
- リストプロパティ型を次のように定義しますQQmlListProperty
- Qtプラグインを定義し、qmldirファイルを作成することで、プラグインライブラリを作成します
「QMLとC++の統合」の概要ドキュメントには、QML拡張機能に追加できるその他の便利な機能が紹介されています。例えば、デフォルトプロパティを使用することで、slices プロパティを使わずにスライスを追加できるようにすることができます:
PieChart {
PieSlice { ... }
PieSlice { ... }
PieSlice { ... }
}あるいは、プロパティ値ソースを使用して、スライスを随時ランダムに追加・削除することもできます:
PieChart {
PieSliceRandomizer on slices {}
}注: QML拡張機能とその機能についてさらに学習するには 、「C++を使用した高度なQML拡張機能の作成」チュートリアルに従ってください。
© 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.