QML (Qt Modeling Language) は、ユーザインタフェースマークアップ言語である。QMLはJavaScriptをベースとした言語であり、アプリケーションのユーザインタフェースをデザインするためのCSSやJSONのような宣言型言語である。この言語はノキアによって開発されたQtのUI作成キットであるQt Quickに関連するものである。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
- Mer
- Ubuntu Touch
- Lumina

## 構文

### 標準的な構文

例:

オブジェクトは型によって指定され、その後に波括弧が続く。オブジェクトの型は常に大文字から始まる。上の例では、`Rectangle`とその子供の`Image`の2つのオブジェクトがある。波括弧の間にはオブジェクトのプロパティなどの情報を指定することができる。プロパティは`プロパティ: 値`の形式で指定することができる。上の例では、`Image`に`source`というプロパティがあり、`pics/logo.png`という値が割り当てられている。プロパティと値はコロンによって区切られている。

各オブジェクトには`id`という特殊な固有のプロパティを与えることができる。`id`を割り当てることで、他のオブジェクトやスクリプトがその`id`が割り当てられたオブジェクトを参照できるようになる。下の例の最初の`Rectangle`には、`myRect`という`id`がある。2番目の`Rectangle`の`width`の値は、`myRect.width`と定義されているが、これは最初の`Rectangle`の`width`の値を参照している。つまり、2番目の`Rectangle`の`width`には、最初の`Rectangle`の`width`と同じ幅が指定されることになる。

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

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

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

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

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

例:

### 状態

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

例:

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

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

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

### アニメーション

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

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

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

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

## 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要素にはマウスの押す・離す・クリックを処理するシグナルハンドラがある。

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

## 開発ツール

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

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