このページの内容

QMLの第一歩

QMLドキュメントの作成

QMLドキュメントは、読みやすく構造化されたレイアウトでオブジェクトの階層を定義します。すべてのQMLドキュメントは、インポートセクションとオブジェクト宣言セクションの2つの部分で構成されています。ユーザーインターフェースで最も一般的に使用される型や機能は、QtQuick インポートで提供されています。

QtQuickモジュールのインポートと使用

Qt Quick モジュールを使用するには、QMLドキュメントでそれをインポートする必要があります。インポートの構文は次のようになります:

import QtQuick

xml-ph-0000@deepl.internalが提供する Qt Quick が提供する型や機能は、これでQMLドキュメント内で使用できるようになります!

オブジェクト階層の定義

QMLドキュメント内のオブジェクト宣言は、ビジュアルシーンに何が表示されるかを定義します。 Qt Quick は、画像やテキストの表示、ユーザー入力の処理を行うオブジェクトなど、すべてのユーザーインターフェースの基本的な構成要素を提供します。

簡単なオブジェクト宣言の例として、中央にテキストが配置された色付きのウィンドウが挙げられます。

Window {
    width: 640
    height: 480
    visible: true
    color: "red"

    Text {
        anchors.centerIn: parent
        text: "Hello, World!"
    }
}

これは、ルートオブジェクトであるWindow と、その子オブジェクトであるText からなるオブジェクト階層を定義しています。Text オブジェクトのparent は自動的にWindow に設定され、同様に、Text オブジェクトはQMLによってWindow オブジェクトのchildren プロパティに追加されます。

すべてをまとめると

上記の例で使用されている `Window ` および `Text ` 型は、いずれも `QtQuick ` インポートによって提供されます。このインポートとオブジェクト宣言を組み合わせると、完全な QML ドキュメントが完成します。

import QtQuick

Window {
    width: 640
    height: 480
    visible: true
    color: "red"

    Text {
        anchors.centerIn: parent
        text: "Hello, World!"
    }
}

このドキュメントを「HelloWorld.qml」として保存すれば、読み込んで表示することができます。

QMLプロジェクトの作成と実行

QMLドキュメントで定義されたグラフィカルシーンを表示するには、次のように読み込みます。 Qt Creatorで読み込むことができます。Qt Creator で新しいQMLプロジェクトを作成するには:

  1. File から「New Project 」を選択し、 Qt Quick ApplicationQt Creator を選択します。
  2. プロジェクト名を入力し、保存先を選択します。
  3. 適切な Qt バージョンを選択し、必要に応じてプロジェクトのバージョン管理設定を構成します。
  4. プロジェクト設定の概要を確認し、プロジェクトのビルドを完了させます。

完了すると、Qt Creator は必要なファイルを生成し、開発用のプロジェクトを開きます。緑色の「実行」ボタンを押すと、アプリケーションが実行されます。赤い長方形の中央に「Hello, World!」というテキストが表示されるはずです。

Qt Creator でのプロジェクトの作成および実行に関する詳細については、以下のページを参照してください:

Controls を使用した QML アプリケーションの作成

Qt Quick には基本的なグラフィカル要素が用意されていますが、Qt Quick Controls には、アプリケーション内で使用できる既製の QML タイプが用意されています。

ApplicationWindow の型を挿入することは、アプリケーション作成の良い出発点となります。アプリケーションのUIは、次のような基本的なレイアウトを持っています:

メニューバー、ツールバー、コンテンツ領域、ステータスバーを備えたアプリケーションウィンドウのレイアウト

各領域内に、さまざまなコントロールを追加して接続することで、アプリケーションを構成できます。たとえば、次のスニペットは、利用可能なスペースの活用方法を示す基本的なアプリケーションです:

//import related modules
import QtQuick
import QtQuick.Controls

//window containing the application
ApplicationWindow {
    width: 640
    height: 480
    visible: true
    //title of the application
    title: qsTr("Hello World")

    //menu containing two menu items
    header: MenuBar {
        Menu {
            title: qsTr("&File")
            Action {
                text: qsTr("&Open...")
                onTriggered: console.log("Open action triggered")
            }
            MenuSeparator { }
            Action {
                text: qsTr("&Exit")
                onTriggered: Qt.quit()
            }
        }
    }

    //Content Area

    //a button in the middle of the content area
    Button {
        text: qsTr("Hello World")
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }
}

このアプリケーションには、2つのメニュー項目と、中央に1つのボタンがあります。「Exit 」メニュー項目をクリックすると、アプリケーションが閉じられます。

また、さまざまなナビゲーション方法や、ボタンやスライダーなどのさまざまなコントロールも用意されています。Qt Creator には、さまざまなコントロールやレイアウトを示す以下のサンプルが用意されています。

このシンプルな「Hello World」アプリケーションにスニペットをコピー&ペーストして、QMLの動作を確認してみてください。

ユーザー入力の処理

QML を使用してユーザーインターフェースを定義する大きな利点の 1 つは、ユーザーインターフェース設計者が、単純な JavaScript 式を使って、イベントに対してアプリケーションがどのように反応すべきかを定義できることです。QML では、これらのイベントを「シグナル」と呼び、シグナルハンドラによって処理されます。

たとえば、次の例を考えてみましょう。

import QtQuick

Window {
    id: root
    width: 200
    height: 100
    color: isRed ? "red" : "blue"
    visible: true

    property bool isRed: true  // Track the color state

    Text {
        anchors.centerIn: parent
        text: "Hello, World!"
    }

    TapHandler {
        onTapped: root.isRed = !root.isRed  // Toggle state
    }
}

qmlこの例は「ClickableHelloWorld.qml」として保存し、QML Runtime (ツール)で実行できます。ユーザーがウィンドウ内のどこかをクリックするたびに、長方形が赤から青に変わります。もう一度タップすると、再び赤に戻ります。

注: TapHandler は タッチイベントに対してもtappedシグナルを発行するため、このコードはモバイルデバイスでも動作します。

キーボードからのユーザー入力も、次のような簡単な式で同様に処理できます:

import QtQuick

Window {
    id: root
    width: 200
    height: 100
    color: "red"
    visible: true

    Text {
        id: myText
        anchors.centerIn: parent
        text: toggle ? "Hello, World!" : "Goodbye, World!"
        focus: true
        property bool toggle: true
        Keys.onReturnPressed: (event)=>{
            myText.toggle = !myText.toggle;
            event.accepted = true;
        }
    }
}

これで、Enterキーを押すたびに、テキストが「Hello, World」と「Goodbye, World」の間で切り替わります。

プロパティのバインディング

オブジェクトとそのプロパティは、QMLドキュメントで定義されるグラフィカルインターフェースの基礎を成しています。QML言語では、プロパティ同士をさまざまな方法でバインドすることができ、これにより非常に動的なユーザーインターフェースを実現できます。

次の例では、各子要素Rectangle のジオメトリが、親要素Window のジオメトリにバインドされています。親要素Window のジオメトリが変更されると、プロパティのバインドにより、各子要素Rectangle のジオメトリが自動的に更新されます。

import QtQuick

Window {
    id: root
    width: 200
    height: 100
    color: "red"
    visible: true


    Rectangle {
        width: root.width / 2
        height: root.height
        color: "blue"
    }

    Rectangle {
        width: root.width / 2
        height: root.height
        x: root.width / 2
        color: "green"
    }
}

アニメーション

プロパティは、アニメーションを介して動的に更新することもできます。QtQuick インポートには、プロパティの値の変化をアニメーション化するために使用できるさまざまなアニメーションタイプが用意されています。次の例では、プロパティにアニメーションを適用し、その結果をText の領域に表示しています:

import QtQuick

Window {
    id: root
    width: 200
    height: 100
    color: "red"
    visible: true

    property int animatedValue

    SequentialAnimation on animatedValue {
        loops: Animation.Infinite
        PropertyAnimation {
            to: 150
            duration: 1000
        }
        PropertyAnimation {
            to: 0
            duration: 1000
        }
    }

    Text {
        anchors.centerIn: parent
        text: root.animatedValue
    }
}

表示される値は、0 から 150 まで周期的に変化します。

再利用のためのカスタム QML タイプの定義

QMLにおける最も重要な概念の一つは、型の再利用です。アプリケーションには、類似したビジュアル型(例えば、複数のプッシュボタンなど)が複数存在することがよくありますが、QMLでは、コードの重複を最小限に抑え、可読性を最大化するために、こうした要素を再利用可能なカスタム型として定義することができます。

たとえば、開発者がMessageLabel.qml ファイル内で新しいMessageLabel 型を次のように定義したとします:

// MessageLabel.qml
import QtQuick

Rectangle {
    height: 50
    property string message: "debug message"
    property var msgType: ["debug", "warning" , "critical"]
    color: "black"

    Column {
        anchors.fill: parent
        padding: 5.0
        spacing: 2
        Text {
            text: msgType.toString().toUpperCase() + ":"
            font.bold: msgType == "critical"
            font.family: "Terminal Regular"
            color: msgType === "warning" || msgType === "critical" ? "red" : "yellow"
            ColorAnimation on color {
                running: msgType == "critical"
                from: "red"
                to: "black"
                duration: 1000
                loops: msgType == "critical" ? Animation.Infinite : 1
            }
        }
        Text {
            text: message
            color: msgType === "warning" || msgType === "critical" ? "red" : "yellow"
            font.family: "Terminal Regular"
        }
    }

}

このタイプは、次のようにアプリケーション内で複数回再利用できるようになります:

// application.qml
import QtQuick
Window {
    id: root
    width: 180
    height: 180
    visible: true
    Column {
        anchors.fill: parent
        padding: 1.5
        topPadding: 10.0
        bottomPadding: 10.0
        spacing: 5
        MessageLabel{
            width: root.width - 2
            msgType: "debug"
        }
        MessageLabel {
            width: root.width - 2
            message: "This is a warning!"
            msgType: "warning"
        }
        MessageLabel {
            width: root.width - 2
            message: "A critical warning!"
            msgType: "critical"
        }
    }
}

このようにして、モジュール化されたユーザーインターフェース型がアプリケーション内で組み立てられ、再利用されます。

独自の再利用可能なコンポーネントの開発方法の詳細については、「QML オブジェクト属性」を参照してください。

次のステップ

QMLの実用例を確認したところで、次のステップに進む準備が整いました。次のページでは、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.