QML文書によるオブジェクトタイプの定義

QMLの中核的な特徴の1つは、QMLアプリケーションのニーズに合わせて、 QMLドキュメントを通してQMLオブジェクトの型を軽量な方法で簡単に定義できることです。標準のQt Quickモジュールでは、QML アプリケーションを構築するためのRectangleTextImage といった様々な型が提供されています。これらの型以外にも、アプリケーション内で再利用する独自の QML 型を簡単に定義することができます。このように独自の型を作成する機能は、あらゆるQMLアプリケーションの構成要素となります。

QMLファイルによるオブジェクト型の定義

カスタム QML オブジェクトタイプの命名

オブジェクトタイプを作成するには、QML文書を<TypeName>.qmlという名前のテキストファイルに記述します。型名には次のような条件があります:

  • 英数字かアンダースコアであること。
  • 大文字で始まること。

この文書がQMLの型定義として自動的に認識されます。また、このようにして定義された型は、QMLの型名を解決する際に、同じローカルディレクトリ内にある他のQMLファイルからも自動的に利用できるようになります。

注意: QMLエンジンはこの方法では自動的にリモートディレクトリを検索しません。ドキュメントをネットワーク経由で読み込む場合は qmldir ファイルを追加する必要があります。QML ドキュメントディレクトリのインポート」を参照してください。

カスタムQMLタイプ定義

例えば、Rectangle とその子MouseArea を宣言したドキュメントを以下に示します。このドキュメントはSquareButton.qml という名前のファイルに保存されています:

// SquareButton.qml
import QtQuick 2.0

Rectangle {
    property int side: 100
    width: side; height: side
    color: "red"

    MouseArea {
        anchors.fill: parent
        onClicked: console.log("Button clicked!")
    }
}

このファイルはSquareButton.qml という名前なので、同じディレクトリにある他のQMLファイルからSquareButton という名前の型として使用することができます。例えば、同じディレクトリにmyapplication.qml というファイルがあれば、SquareButton という型を参照することができます:

// myapplication.qml
import QtQuick 2.0

SquareButton {}

これは、SquareButton.qml で定義されているように、MouseArea を内側に持つ 100 x 100 の赤いRectangle を作成します。このmyapplication.qml ドキュメントがエンジンに読み込まれると、SquareButton.qml ドキュメントをコンポーネントとして読み込み、それをインスタンス化してSquareButton オブジェクトを作成します。

SquareButton 型はSquareButton.qml で宣言された QML オブジェクトのツリーをカプセル化したものです。QMLエンジンがこの型からSquareButton オブジェクトをインスタンス化するとき、SquareButton.qml で宣言されたRectangle ツリーからオブジェクトをインスタンス化することになります。

注意: ファイル名の大文字と小文字は、ファイルシステム(特にUNIX)によっては重要です。ファイル名の大文字と小文字は、QMLの型名と正確に一致させることを推奨します。例えば、BoX.qml ではなく、Box.qml のようにします。

インラインコンポーネント

例えば、小さなデリゲートを複数のビューで再利用する場合などです。実際に型を公開する必要はなく、インスタンスを作成するだけでよいのであれば、Component 。しかし、コンポーネント型でプロパティを宣言したい場合や、複数のファイルで使用したい場合は、Component 。その場合は、インライン・コンポーネントを使うことができる。インライン・コンポーネントは、ファイルの内部で新しいコンポーネントを宣言する。そのための構文は

component <component name> : BaseType {
    // declare properties and bindings here
}

インライン・コンポーネントを宣言するファイルの中では、型は単にその名前で参照することができる。

// Images.qml
import QtQuick

Item {
    component LabeledImage: Column {
        property alias source: image.source
        property alias caption: text.text

        Image {
            id: image
            width: 50
            height: 50
        }
        Text {
            id: text
            font.bold: true
        }
    }

    Row {
        LabeledImage {
            id: before
            source: "before.png"
            caption: "Before"
        }
        LabeledImage {
            id: after
            source: "after.png"
            caption: "After"
        }
    }
    property LabeledImage selectedImage: before
}

他のファイルでは、その前にそれを含むコンポーネントの名前を付けなければなりません。

// LabeledImageBox.qml
import QtQuick

Rectangle {
    property alias caption: image.caption
    property alias source: image.source
    border.width: 2
    border.color: "black"
    Images.LabeledImage {
        id: image
    }
}

注: インライン・コンポーネントは、宣言されたコンポーネントとスコープを共有しません。以下の例では、ファイルB.qmlのA.MyInlineComponent 。B.qmlにはidとしてroot が存在しないため、作成時にReferenceErrorが発生します。したがって、インラインコンポーネントの一部ではないオブジェクトを参照しないことをお勧めします。

// A.qml
import QtQuick

Item {
    id: root
    property string message: "From A"
    component MyInlineComponent : Item {
        Component.onCompleted: console.log(root.message)
    }
}
// B.qml
import QtQuick

Item {
    A.MyInlineComponent {}
}

注意: インライン・コンポーネントを入れ子にすることはできません。

現在のディレクトリ以外で定義された型のインポート

SquareButton.qmlmyapplication.qml と同じディレクトリにない場合、SquareButton の型は、myapplication.qmlimport文で特別に利用可能にする必要があります。ファイルシステム上の相対パスからインポートするか、インストールされたモジュールとしてインポートすることができます。

カスタム型のアクセス可能な属性

.qmlファイルのルートオブジェクト定義では、QML型が利用可能な属性を定義します。このルートオブジェクトに属するすべてのプロパティ、シグナル、メソッドは、 それがカスタムで宣言されたものであれ、ルートオブジェクトの QML タイプに由来するものであれ、 外部からアクセス可能であり、このタイプのオブジェクトを読み込んだり、変更したりすることが できます。

例えば、上記のSquareButton.qml ファイルのルートオブジェクトのタイプはRectangle です。つまり、Rectangle で定義されたプロパティはSquareButton のオブジェクトに対して変更することができます。以下のコードでは、SquareButton 型のルート・オブジェクトRectangle のプロパティの一部をカスタマイズした値を持つ3つのSquareButton オブジェクトを定義しています:

// application.qml
import QtQuick 2.0

Column {
    SquareButton { side: 50 }
    SquareButton { x: 50; color: "blue" }
    SquareButton { radius: 10 }
}

カスタム QML タイプのオブジェクトがアクセスできる属性には、オブジェクトに対して追加的に定義されたカスタムプロパティメソッドシグナルが含まれます。例えば、SquareButton.qmlRectangle が以下のように定義され、さらにプロパティ、メソッド、シグナルが追加されていたとします:

// SquareButton.qml
import QtQuick 2.0

Rectangle {
    id: root

    property bool pressed: mouseArea.pressed

    signal buttonClicked(real xPos, real yPos)

    function randomizeColor() {
        root.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
    }

    property int side: 100
    width: side; height: side
    color: "red"

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: (mouse)=> root.buttonClicked(mouse.x, mouse.y)
    }
}

どのSquareButton オブジェクトも、ルートRectangle に追加されたpressed プロパティ、buttonClicked シグナル、randomizeColor() メソッドを利用することができます:

// application.qml
import QtQuick 2.0

SquareButton {
    id: squareButton

    onButtonClicked: (xPos, yPos)=> {
        console.log("Clicked", xPos, yPos)
        randomizeColor()
    }

    Text { text: squareButton.pressed ? "Down" : "Up" }
}

SquareButton.qml で定義されたid の値は、SquareButton オブジェクトからはアクセスできないことに注意してください。id 値は、コンポーネントが宣言されたコンポーネントスコープからのみアクセス可能だからです。上記のSquareButton オブジェクト定義は、MouseArea の子を参照するために、mouseArea を参照することはできません。また、squareButton ではなくrootid を持っていたとしても、SquareButton.qml で定義されたルートオブジェクトの同じ値のid と衝突することはありません。

本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。