QML (Qt Modeling Language) は、である。QMLはJavaScriptをベースとした言語であり、アプリケーションのユーザインタフェースをデザインするためのCSSやJSONのような宣言型言語である。この言語はノキアによって開発されたQtのUI作成キットであるに関連するものである。Qt Quickはタッチ入力と流体アニメーション (60 fps) とユーザーエクスペリエンスが重要となるモバイルアプリケーションでしばしば使用されている。QMLはQt 3Dと共に3Dシーンの描画と「フレームグラフ」のレンダリングのためにも使用される。QMLドキュメントは階層的なオブジェクトツリーを記述する。Qtに同梱されているQMLモジュールには基本的なグラフィカルビルディングブロック (長方形、画像など)、モデリングコンポーネント (FolderListModel、XmlListModelなど)、動作コンポーネント (タップハンドラ、ドラッグハンドラ、状態、トランジション、アニメーションなど)、より複雑なコントロール (ボタン、スライダー、ドロワ、メニューなど) が含まれている。これらの単純な要素を組み合わせることで、インターネットに対応したアプリケーションなどの複雑なものを作成することができる。

QMLの要素は標準的なJavaScriptによって拡張することができ、インライン展開されたものと外部ファイルからのものの両方を使用することができる。また、Qtで使用されているC++コンポーネントによって統合と拡張することもできる。

QMLではV4と呼ばれるJavaScriptエンジンをQt 5.2から使用している。Qt Quickは2Dとそれに基づいたUIフレームワークである。これらは全てQt Declarativeモジュールの一部であるが、この技術はもはやQt Declarativeとは呼ばれていない。

QMLとJavaScriptはQt Quickコンパイラによって機械語にコンパイルすることができる。或いは、コンパイル済みのQMLを動的に格納し、次回起動時に高速起動することができるQMLキャッシュファイル形式がある。

採用例 
 KDE Plasma 4とKDE Plasma 5
 Liri
 SDDM
 reMarkable
 Unity2D
 Sailfish OS
 BlackBerry 10
 MeeGo
 Maemo
 Tizen
 
 Ubuntu Touch
 Lumina

構文

標準的な構文 
例:

 import QtQuick 2.9  // import from Qt 5.9

 Rectangle {
     id: canvas
     width: 250
     height: 200
     color: "blue"

     Image {
         id: logo
         source: "pics/logo.png"
         anchors.centerIn: parent
         x: canvas.height / 5
     }
 }

オブジェクトは型によって指定され、その後に波括弧が続く。オブジェクトの型は常に大文字から始まる。上の例では、Rectangleとその子供のImageの2つのオブジェクトがある。波括弧の間にはオブジェクトのプロパティなどの情報を指定することができる。プロパティはプロパティ: 値の形式で指定することができる。上の例では、Imageにsourceというプロパティがあり、pics/logo.pngという値が割り当てられている。プロパティと値はコロンによって区切られている。
 idプロパティ
各オブジェクトにはidという特殊な固有のプロパティを与えることができる。idを割り当てることで、他のオブジェクトやスクリプトがそのidが割り当てられたオブジェクトを参照できるようになる。下の例の最初のRectangleには、myRectというidがある。2番目のRectangleのwidthの値は、myRect.widthと定義されているが、これは最初のRectangleのwidthの値を参照している。つまり、2番目のRectangleのwidthには、最初のRectangleのwidthと同じ幅が指定されることになる。

 Item {
     Rectangle {
         id: myRect
         width: 120
         height: 100
     }
     Rectangle {
         width: myRect.width
         height: 200
     }
 }

idは小文字かアンダースコアで始まり、ラテン文字・数字・アンダースコア以外の文字は使用できない。

プロパティバインディング 
プロパティバインディングは、宣言的な方法でプロパティの値を指定する。のパラダイムに従って、他のプロパティまたはデータの値が更新された場合に、プロパティの値が自動的に更新される。

プロパティバインディングはJavaScriptの式が割り当てられるたびにQMLに暗黙的に作成される。以下の例では、2つのプロパティバインディングを使用して、長方形の大きさとotherItemの大きさを繋げている。

 Rectangle {
     width: otherItem.width
     height: otherItem.height
 }

QMLの処理系は標準に準拠したJavaScriptエンジンを拡張したものなので、有効なJavaScriptの式は全てプロパティバインディングとして使用することができる。プロパティバインディングはオブジェクトのプロパティに接続したり、関数呼び出しを作成したり、DateやMathなどのの組み込みオブジェクトを使用することもできる。

例:

 Rectangle {
     function calculateMyHeight {
         return Math.max(otherItem.height, thirdItem.height);
     }
     anchors.centerIn: parent
     width: Math.min(otherItem.width, 10)
     height: calculateMyHeight
     color: width > 10 ? "blue" : "red"
 }

状態 
状態は意味論単位でプロパティの変更を結び付ける仕組みである。例えば、ボタンは押された状態とそうでない状態を持ち、アドレス帳アプリケーションは連絡先のための読み取り専用の状態と編集可能な状態を持つことができる。全ての要素は暗黙的な基本状態を持つ。これ以外の全ての状態は、基本状態と異なるこれらの要素のプロパティと値を列挙することで記述される。

例:

基本状態ではmyRectは 0, 0 に配置される。movedでは50, 50 に配置される。マウス領域内をクリックすると状態が基本状態からmovedに変化し、長方形が移動する。

 import QtQuick 2.0

 Item {
     id: myItem
     width: 200; height: 200

     Rectangle {
         id: myRect
         width: 100; height: 100
         color: "red"
     }
     states: [
         State {
             name: "moved"
             PropertyChanges {
                 target: myRect
                 x: 50
                 y: 50
             }
         }
     ]
     MouseArea {
         anchors.fill: parent
         onClicked: myItem.state = 'moved'
     }
 }

状態の変更はトランジションを使うことでアニメーションにすることができる。

例えば、下記のコードを上のItemに追加すると、movedへの遷移を動的なものにすることができる。

 transitions: [
     Transition {
         from: "*"
         to: "moved"
         NumberAnimation { properties: "x,y"; duration: 500 }
     }
  ]

アニメーション 
QMLのアニメーションは、オブジェクトのプロパティをアニメーションにすることで行われる。real・int・color・rect・point・size・vector3dプロパティは全てアニメーションに対応している。

QMLは基本的なプロパティアニメーション・トランジション・プロパティ動作の3つの主要な形式のアニメーションに対応している。

アニメーションの最も簡単な形式はPropertyAnimationで、上の一覧の全てのプロパティ型をアニメーション化することができる。プロパティアニメーションは、プロパティシンタックスのアニメーションを使用して値のソースを指定することができる。これはアニメーションを繰り返す場合に特に便利である。

次の例では弾む効果を作成している。

 Rectangle {
     id: rect
     width: 120; height: 200

     Image {
         id: img
         source: "pics/qt.png"
         x: 60 - img.width/2
         y: 0

         SequentialAnimation on y {
             loops: Animation.Infinite
             NumberAnimation { to: 200 - img.height; easing.type: Easing.OutBounce; duration: 2000 }
             PauseAnimation { duration: 1000 }
             NumberAnimation { to: 0; easing.type: Easing.OutQuad; duration: 1000 }
         }
     }
 }

Qt/C++との統合 
QMLを使用するときにQt/C++の知識は不要で、Qtを経由して簡単に拡張することができる。QObjectから派生したC++クラスは、QMLでインスタンス化できる型として簡単に登録することができる。

ソフトウェアアーキテクチャ 
 QObject signals - JavaScriptでコールバックをトリガーすることができる。
 QObject slots - JavaScriptで呼び出す関数として利用できる。
 QObject properties - JavaScriptの変数やバインディングとして利用できる。
 QWindow - ウィンドウがウィンドウ内にQMLシーンを作成する。
 Q*Model - データバインディングで直接使用される (QAbstractItemModelなど)。

シグナルハンドラ 
シグナルハンドラはJavaScriptのコールバックであり、イベントに応じて強制的にアクションを取ることができる。例えば、MouseArea要素にはマウスの押す・離す・クリックを処理するシグナルハンドラがある。

 MouseArea {
     onPressed: console.log("mouse button pressed")
 }

全てのシグナルハンドラの名前は「on」から始まる。

開発ツール 
QMLとJavaScriptは非常に似ているので、JavaScriptに対応する殆ど全てのソースコードエディタで利用することができる。但し、シンタックスハイライト・コード補完・統合されたヘルプ・WYSIWYGエディタの完全なサポートは 2.1以降かその他の統合開発環境で利用することができる。

QMLの実行ファイルはQMLをスクリプトとして実行するのに利用できる。QMLファイルがシバンで始まる場合には直接実行することができる。しかし、アプリケーションを追加するためにパッケージングするとき (特にモバイルプラットフォーム) には、単純なC++ランチャーを作成し、必要なQMLファイルをリソースとしてパッケージングする必要がある。