QML
パラダイム | 宣言型プログラミング、リアクティブプログラミング |
---|---|
登場時期 | 2009年 |
開発者 | Qt Project |
最新リリース | 5.12 LTS/ 2018年12月6日[1] |
影響を受けた言語 | JavaScript、Extensible Application Markup Language、JavaScript Object Notation、Qt |
ウェブサイト | QML Applications |
拡張子 | .qml |
QML (Qt Modeling Language[2]) は、ユーザインタフェースマークアップ言語である。QMLはJavaScriptをベースとした言語であり、アプリケーションのユーザインタフェースをデザインするためのCSSやJSONのような宣言型言語である。この言語はノキアによって開発されたQtのUI作成キットであるQt Quickに関連するものである。Qt Quickはタッチ入力と流体アニメーション (60 fps) とユーザーエクスペリエンスが重要となるモバイルアプリケーションでしばしば使用されている。QMLはQt 3D[3]と共に3Dシーンの描画と「フレームグラフ」のレンダリングのためにも使用される。QMLドキュメントは階層的なオブジェクトツリーを記述する。Qtに同梱されているQMLモジュールには基本的なグラフィカルビルディングブロック (長方形、画像など)、モデリングコンポーネント (FolderListModel、XmlListModelなど)、動作コンポーネント (タップハンドラ、ドラッグハンドラ、状態、トランジション、アニメーションなど)、より複雑なコントロール (ボタン、スライダー、ドロワ、メニューなど) が含まれている[4]。これらの単純な要素を組み合わせることで、インターネットに対応したアプリケーションなどの複雑なものを作成することができる。
QMLの要素は標準的なJavaScriptによって拡張することができ、インライン展開されたものと外部ファイルからのものの両方を使用することができる。また、Qtで使用されているC++コンポーネントによって統合と拡張することもできる。
QMLではV4と呼ばれるJavaScriptエンジン[注釈 1]をQt 5.2から使用している[5][6]。Qt Quickは2Dシーングラフとそれに基づいたUIフレームワークである。これらは全てQt Declarativeモジュールの一部であるが、この技術はもはやQt Declarativeとは呼ばれていない。
QMLとJavaScriptはQt Quickコンパイラによって機械語にコンパイルすることができる[7]。或いは、コンパイル済みのQMLを動的に格納し、次回起動時に高速起動することができるQMLキャッシュファイル形式がある[8]。
採用例
[編集]- KDE Plasma 4[9]とKDE Plasma 5
- Liri
- SDDM
- reMarkable[10][11]
- Unity2D[12]
- Sailfish OS[13][14]
- BlackBerry 10[15]
- MeeGo[16]
- Maemo[17]
- Tizen[18]
- Mer[19]
- Ubuntu Touch[20]
- Lumina[21]
構文
[編集]標準的な構文
[編集]例:
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など)[22]。
シグナルハンドラ
[編集]シグナルハンドラはJavaScriptのコールバックであり、イベントに応じて強制的にアクションを取ることができる。例えば、MouseArea要素にはマウスの押す・離す・クリックを処理するシグナルハンドラがある。
MouseArea {
onPressed: console.log("mouse button pressed")
}
全てのシグナルハンドラの名前は「on」から始まる。
開発ツール
[編集]QMLとJavaScriptは非常に似ているので、JavaScriptに対応する殆ど全てのソースコードエディタで利用することができる。但し、シンタックスハイライト・コード補完・統合されたヘルプ・WYSIWYGエディタの完全なサポートはQt Creator 2.1以降かその他の統合開発環境で利用することができる。
QMLの実行ファイルはQMLをスクリプトとして実行するのに利用できる。QMLファイルがシバンで始まる場合には直接実行することができる。しかし、アプリケーションを追加するためにパッケージングするとき (特にモバイルプラットフォーム) には、単純なC++ランチャーを作成し、必要なQMLファイルをリソースとしてパッケージングする必要がある。
脚注
[編集]注釈
[編集]出典
[編集]- ^ “Qt 5.12 LTS Released”. Qt Blog (2018年12月6日). 2018年12月13日閲覧。
- ^ Qt Declarative API Changes - ウェイバックマシン(2014年11月13日アーカイブ分)
- ^ “Qt 3D Overview”. The Qt Company. 2018年12月13日閲覧。
- ^ “All QML Types”. The Qt Company. 2018年12月13日閲覧。
- ^ Lars Knoll (2013年4月15日). “Evolution of the QML engine, part 1”. 2018年12月13日閲覧。
- ^ “What's New in Qt 5.2”. The Qt Company. 2018年12月13日閲覧。
- ^ “Qt Quick Compiler”. The Qt Company. 2018年12月13日閲覧。
- ^ “Deploying QML Applications”. The Qt Company. 2018年12月13日閲覧。
- ^ “Development/Tutorials/Plasma4/QML/GettingStarted”. KDE. 2018年12月13日閲覧。
- ^ “Developing for the reMarkable tablet”. KDE (2017年12月1日). 2018年12月13日閲覧。
- ^ “reHackable-HelloWorld”. GitHub. 2018年12月13日閲覧。
- ^ Michael Larabel (2013年3月4日). “Ubuntu's Unity Written In Qt/QML For "Unity Next"”. 2018年12月13日閲覧。
- ^ “Tutorial - Combining C++ with QML”. SailfishOS. 2018年12月13日閲覧。
- ^ “Tutorial - QML Live Coding With Qt QmlLive”. SailfishOS. 2018年12月13日閲覧。
- ^ “QML fundamentals”. BlackBerry. 2018年12月13日閲覧。
- ^ Ash (2011年2月23日). “MeeGo and Qt / QML demos assault MWC”. 2018年12月13日閲覧。
- ^ “QML”. Maemo. 2018年12月13日閲覧。
- ^ “Qt Launches on Tizen with Standard Look and Feel”. Qt for Tizen Blog (2013年5月20日). 2018年12月13日閲覧。
- ^ “Mer Project”. Mer Project. 2018年12月13日閲覧。
- ^ “QML - the best tool to unlock your creativity”. Canonical. 2018年12月13日閲覧。
- ^ Josh Smith (2018年5月2日). “Looking at Lumina Desktop 2.0”. 2018年12月13日閲覧。
- ^ “QAbstractItemModels in QML views”. The missing pieces (2010年4月22日). 2018年12月13日閲覧。
関連項目
[編集]外部リンク
[編集]- 公式ウェブサイト
- First Steps with QML
- Creating Qt Quick Projects
- The QML Reference
- QML Coding Conventions
- Qt Quick Examples and Tutorials
- Qt Blog
- A Book about Qt5