QtQuick の Singleton 機能の使い方

enum 使いたいとかクラスメソッドみたいなのを使いたいとか色々要望があった QtQuick ですが、Qt 5.2 あたりで Singleton 対応がなされたようなので試してみました。

  1. Singleton にする .qml ファイルの上の方に pragma Singleton と書く。
  2. qmldir ファイルを作成し、singleton MySingleton MySingleton.qml と書く。
  3. 使用する qml ファイルで qmldir のあるディレクトリを明示的に import する。import ‘.’

参照:int qmlRegisterSingletonType(const QUrl & url, const char * uri, int versionMajor, int versionMinor, const char * qmlName)

それでは、QtQuick のソースツリーに含まれる Singleton 関係のテストコード を見ながら使い方を探っていきましょう。

singletonTest1.qml

import QtQuick 2.0
import "singleton"

Item {
    property int value1: SingletonType.testProp1;
    property string value2: "Test value: " + SingletonType.testProp3;
}

singleton ディレクトリ を import しています。このディレクトリに含まれる SingletonType というエレメントが Singleton になっており、メンバ変数に SingletonType.testProp1SingletonType.testProp3 のような記述でアクセスしています。

singleton/qmldir は以下のようになっていて、ここで SingletonType エレメントを Singleton として使用できるようにしています。

singleton SingletonType SingletonType.qml

singleton/SingletonType.qml はファイルの先頭部に pragma Singleton と記述してあります。

import QtQuick 2.0
pragma Singleton

Item {
     id: singletonId

     property int testProp1: 125
     property int testProp2: 25
     property int testProp3: -55

     width: 25; height: 25

     Rectangle {
         id: rectangle
         border.color: "white"
         anchors.fill: parent
     }
}

singletonTest2.qml

import QtQuick 2.0
import "singleton"

Item {
    property variant singleton1: SingletonType;
}

プロパティを一つ作成し、そこに Singleton の SingletonType エレメントを指定しています。

singletonTest3.qml

import QtQuick 2.0
import "singleton"

Item {
    property QtObject singleton2: SingletonType;
}

今回はプロパティの型を SingletonType の基底エレメントの QtObject としています。

singletonTest4.qml

import QtQuick 2.0
pragma Singleton

Item {

}

実行するファイルを Singleton にしてみましたが、これは No matching type found, pragma Singleton files cannot be used by QQmlComponent. というエラーになります。

singletonTest5.qml

import QtQuick 2.0
import "singleton" as TestNameSpace

Item {
    property int value1: TestNameSpace.SingletonType.testProp1;
    property string value2: "Test value: " + TestNameSpace.SingletonType.testProp3;
    property variant singletonInstance: TestNameSpace.SingletonType;
}

名前空間を使用することも可能です。

singletonTest6.qml singletonTest7.qml singletonTest8.qml

Singleton エレメントを C++ 側で作成した場合のテストです。

singletonTest9.qml

import QtQuick 2.0
import "singleton"

Item {
    SingletonType {}
}

Singleton のエレメントをインスタンス化していますが、5:5:Composite Singleton Type SingletonType is not creatable. というエラーになります。

インスタンス化はできないので、singletonTest2.qml のようにプロパティを一つ作成して代入するのが良さそうですね。

singletonTest10.qml

import QtQuick 2.0
import "singleton"

Item {
    property SingletonType test
}

SingletonType 型のプロパティを作成していますが、4:1:Composite Singleton Type SingletonType is not creatable. というエラーになります。

singletonTest11.qml

import QtQuick 2.0
import "singleton"

Item {
    id: test

    property int value1: SingletonType.testProp1;
    property string value2: "Test value: " + SingletonType.testProp3;

    signal customSignal(SingletonType type)

    onCustomSignal: {
        type.testProp1 = 99
    }

    Component.onCompleted: test.customSignal(SingletonType)
}

シグナルの引数には使えるようです。

この他にもいくつか Singleton 関係のテストがありますが、長くなったのでこの記事ではここまでにしておきます。