Qt Quick 入門 第4回: 画像やマウスを使おう

はじめに

Qt 4.7 がリリースされました。これまでは(仕様はほぼ固まっていたとはいえ)正式リリース前の QML を使っていたため、環境のセットアップなどが不便でしたが、正式リリースされたことで今後は以前よりも楽に QML を使うことができます。

さて、前回の冒頭で Qt Creator 2.0.1 を使用すると述べましたが、Qt Creator 2.0.1 には QMLViewer が含まれていないことを確認していませんでした。このため、Qt Creator 2.0.1 のみがインストールされている環境では QML アプリケーションの実行ができません。QMLViewer も含まれる Qt 4.7 もしくは Qt SDK 2010.5 を ダウンロード のページから入手してインストールをお願いします。

前回は QML で書かれた「Hello World」を例にして、QML の基礎を学んでいただきました。[qml Rectangle] や [qml Text] といった要素が使われていましたが、今回は QML を編集し、それ以外の要素を使ってみようと思います。

QML の描画要素

QML の要素は "[qt "QML Elements" l=qdeclarativeelements]" に一覧がありますが、その中から Qt モジュールに含まれている描画に関連する基本的な要素を抜き出したのが下記のリストです。

  • [qml AnimatedImage]: アニメーションGIFのようなアニメーションする画像を表示します
  • [qml BorderImage]: 画像で作成された枠を表示します
  • [qml Image]: 画像を表示します
  • [qml Rectangle]: 矩形を表示します
  • [qml Text]: テキストを表示します
  • [qml TextEdit]: 複数行のテキストの入力/編集が行えます
  • [qml TextInput]: 一行のテキストの入力/編集が行えます

この他に [qml Item] も QML で描画を行う際の基本要素となりますが、Item はそれ自身は描画を行わない要素であるため、上記のリストからは除外しています。

上記の要素は(テキスト系の入力がありますが)基本的に描画のみを行います。それだけでは UI の作成は不可能ですので下記のような入力系の処理要素を組み合わせてアプリケーションや UI を作成する必要があります。

  • [qml Keys]: キー入力を処理します
  • [qml KeyNavigation]: カーソルキーによるフォーカス移動をサポートします
  • [qml MouseArea]: マウス関係の処理を行います

QML では上述の要素に加えて、レイアウトや状態遷移、アニメーションなどの要素を使用してアプリケーション や UI を作成していきます。今回は描画要素として [qml Image] を、マウスのクリックの処理に [qml MouseArea] を使用します。

プロジェクトの作成

まずは前回と同様に新規に QML アプリケーションのプロジェクトを作成します。名前は「qml-example」とします。「ファイル(F)」メニューの「ファイル/プロジェクトの新規作成(N)...」を選びます。「新規作成」ダイアログが表示されますので、「他のプロジェクト」の中から「Qt QML アプリケーション」を選択して「選択(C)...」をクリックします。

「新しい QML プロジェクト」ダイアログが表示され、パスの入力が促されます。「名前:」欄と「パス:」欄にそれぞれプロジェクトの名前とパスを入力してください。今回のプロジェクト名は「qml-example」にしました。パスはスペースを含まない任意のパスを指定してください。入力したら「続き」をクリックしてください。

新しい QML プロジェクト - プロジェクト名とパス

「プロジェクト管理」の画面ではそのまま「終了」をクリックしてください。

新しい QML プロジェクト - プロジェクト管理

作成した「qml-example」プロジェクトとそこに含まれる「qml-example.qml」が編集用に開かれます。ファイルの内容は前回作成した「helloqml.qml」と同じ以下のような内容になります(一行目のコメントは説明のために追加したものです)。

なお、QML におけるコメントの表記法は C++ / JavaScript と同様に「//」か「/* 〜 */」を用います。「//」の場合はそこから行末までが、「/*」と「*/」で囲った場合にはその間がコメントとして無視されます。

// リストA: Hello World
import Qt 4.7

Rectangle {
width: 200
height: 200
Text {
x: 66
y: 93
text: "Hello World"
}
}

このソースを実行すると以下の画像のように中央に「Hello World」とのみ表示されるアプリケーションが起動します。

Hello World

まずは画像を配置するために中央の Text を下に移動させてスペースを確保しましょう。この Text は後で利用しますので、削除しないでください。「デザイン」ボタンを押して Qt Quick デザイナに移動します。中央の Text 「Hello World」をドラッグしてそのまま枠の下側まで移動させてください。

Qt Quick デザイナ: Text 要素を移動する

それ以外にも、右側の「プロパティ」の「ジオメトリ」タブで Y の値を変更したり、Qt Quick デザイナを使用せずに、QML エディタで Text の中の「y: 93」となっている数字を変更しても同様に Text 要素の位置を変更できます。お好きな方法で編集してください。Y の値を直接変更する場合には 175 あたりを目安にしてください。Qt Quick デザイナで編集した場合には「編集」ボタンを押して QML エディタで Text の Y の値が変更されていることを確認してみてください。

Qt Quick デザイナ: Text 要素の移動後

Text を下側に移動させたら、画像を上側に表示してみましょう。QML エディタでコードを表示している場合は再び Qt Quick デザイナに戻って、ウィンドウの左下側にある「ライブラリ」ペインの中から Image 要素をドラッグして、中央のアプリケーションのウィンドウにドロップします。場所は左上に近いところにしてください。

Qt Quick デザイナ: Image 要素の追加

続いて、表示する画像を指定します。Image をドロップした直後ですと Image 要素が選択された状態になっていると思いますので、右側の「プロパティ」ペインの「Image」タブを選択し、「画像」の「ソース」を変更してください。今回は http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png を使います。この URL をそのままコピーするか、適当なディレクトリにダウンロードして、「...」ボタンでそのファイルを選択してください。

Qt Quick デザイナ: Image 要素のソースを指定する

この Qt のロゴのサイズは 87×100 ですが、Image のサイズは 100×100になっていますので、表示が少し横に間延びしています。「プロパティ」ペインの「ジオメトリ」タグの「サイズ」「W」をリセットして画像の幅に合わせます。このポップアップメニューは「サイズ」プロパティの「W」と「100.0」の間にある○印をクリックすると出てきます。同様に「H」についてもリセットしてください。サイズをリセットした場合、Image 要素のサイズはソースに指定された画像のサイズと同じになります。その場合、QML  のソースからは Image 要素の [qml '' width e=item], [qml '' height e=item] がそれぞれ削除されます。

Qt Quick デザイナ: Image 要素の幅(W)のリセット

ここまでの変更を「編集」ボタンを押して QML エディタに戻って確認してみます。最初のリストAと異なる部分を [b数字] 形式のコメントで示しています。

// リストB: Image 要素追加後
import Qt 4.7

Rectangle {
width: 200
height: 200
Text {
x: 66
y: 175 // [b1]
text: "Hello World"
}

Image { // [b2]
id: image1 // [b3]
x: 5 // [b4]
y: 5 // [b5]
source: "http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png"
// [b6]
}
}

最初のソース(リストA)と比べると、 Text 要素の y プロパティの値([b1])が異なるほかに、Image 要素が追加されています。Image 要素の各プロパティの説明を以下に記載します。

[b2]: Image 要素で画像を表示します。

[b3]: この Image 要素の ID を指定しています。今回は使用していませんが、他の要素からこの Image 要素を参照する際に使用します。

[b4][b5]: 前回説明した Rectangle や Text で使用されているのと同様に [qml Item] 要素のプロパティです。この Image 要素の位置([qml '' x e=item], [qml '' y e=item])を指定しています。

[b6]: Image 要素が表示する画像のソースを指定します。指定するパスは文字列であるため QML エディタで直接記述する際には、「"」でくくるのを忘れないようにしてください。上記の例では URL 形式でネットワーク上の画像ファイルを指定していますが、ローカルのファイルシステムにあるファイルを相対/絶対パスで指定することも可能です。

画像が表示できたら、今度はボタンを作成して、マウスを使用してみましょう。QML には Qt の [qt QPushButton] のようなボタンそのものの要素は存在しません。Image や Text 等の描画要素とマウスの入力を検出する MouseArea 要素を組み合わせて使用します。今回は最初にウィンドウの下側に移動させた Text 要素をマウスに対応させてボタンとします。

まずは Text 要素の文字列をボタンらしく「Click」に変更しましょう。QML エディタで text プロパティを直接編集することも可能ですが、今回は Qt Quick デザイナでの編集方法を記載しておきます。まずは「デザイン」ボタンを押して Qt Quick デザイナに移行します。「Hello World」 Text 要素をクリックして選択して、「プロパティ」ペインの「Text」タブをクリックして表示します。真ん中あたりに「Hello World」と表示された「テキスト」要素がありますので、ここをクリックして「Click」に編集します。

Qt Quick デザイナ: Text 要素のテキストの変更

次に、Text 要素をマウスに対応させます。マウスに対応させるにはその範囲に MouseArea 要素を置く必要があります。左下の「ライブラリ」ペインから「Qt - Interaction」にある「MouseArea」をウィンドウの適当な位置に置いてください。

Qt Quick デザイナ: MouseArea 要素の追加

次に、この MouseArea を Text の子要素にします。Image のような大きな要素の子供にする場合は、左の「ライブラリ」からドラッグ&ドロップするときに MouseArea を Image に重ねておくことで親子関係を築くことができますが、Text 要素は小さいためにうまくいきません。そのため、左上の「ナビゲータ」ペインを使用します。「ナビゲータ」ペインの「mouse_area1」をドラッグして、その上にある「Text」に重ねてドロップしてください。

Qt Quick デザイナ: MouseArea 要素の親子関係の変更

うまく「mouse_area1」が「Text」の子要素になったら、次は「mouse_area1」と「Text」の座標を一致させます。「Text」全体をボタンとするため、まずは「mouse_area1」が選択されている状態で「プロパティ」ペインの「ジオメトリ」タブをクリックして表示させます。「ジオメトリ」が表示されたら、その中の「レイアウト」の下の「アンカー」ボタンの中で真ん中付近の四方を囲まれているボタンを押してください。下記の図のように「Click」と同じ座標、サイズに「mouse_area1」が変更されます。

Qt Quick デザイナ: MouseArea 要素のアンカーの設定

これで「Click」でクリックなどのマウスの操作を取得することができるようになります。今回はクリックを検出してログにメッセージを出力させてみましょう。

「編集」ボタンを押して QML エディタに戻ってください。MouseArea 要素が新しく追加されていますが、その中に「onClicked: console.log("Clicked")」という行を追加してください。修正後のソースは以下のようになります。リストBから変更した箇所を[c番号]形式のコメントでマークしました。

// リストC: ボタンの作成後
import Qt 4.7

Rectangle {
width: 200
height: 200
Text {
x: 66
y: 175
text: "Click" // [c1]

MouseArea { // [c2]
id: mouse_area1 // [c3]
anchors.fill: parent // [c4]
onClicked: console.log("Clicked") // [c5]
}
}

Image {
id: image1
x: 5
y: 5
source: "http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png"
}
}

[c1]: Text の文字列を変更しました

[c2]: MouseArea 要素でマウスのクリックを検出します

[c3]: この MouseArea 要素の ID です

[c4]: この MouseArea 要素の座標およびサイズを親要素(parent)である Text と同じ値にしています。 [qml "" anchors.fill e=item] はレイアウトを指定する Item 要素のプロパティです。レイアウトに関しては後日説明する予定です。

[c5]: [qml onClicked e=mousearea s=onClicked] でその MouseArea がクリックされたときのアクションを指定します。ここでは JavaScript の console.log() を使用してメッセージ”Clicked"を出力しています。

このように QML では JavaScript をシームレスに使用して様々なアクションを行うことができます。

ここまで、QML アプリケーションの編集が終わったら、セーブして実行してみてください。ウィンドウが表示されたら「Click」をクリックして、「アプリケーション出力」ペインに「Clicked」と表示されることを確認してみてください。

qml-example

Qt Creator: アプリケーション出力

なお、Image 要素のソースに Web 上の画像をそのまま指定している場合、アプリケーションの実行から画像の表示までに時間がかかることがあります。すぐに表示させたい場合にはローカルにファイルをコピーしてそちらを指定してください。

まとめ

今回は画像を表示する Image 要素とマウスを扱う MouseArea 要素を使ってみましたが、いかがでしたでしょうか。Text と MouseArea を使用してボタンを作っているところは手間に思われる方もいらっしゃるかと思います。QML そのものにはボタンなどのよく使われる要素が欠けているためこのような実装を行いましたが、ボタンやスライダーなどよく使われる UI の部品は Qt の [qt 'QML Examples and Demos' l=qdeclarativeexamples] に含まれる UI Components や Qt Developer Network の Qt Quick Componentsに実装されたコンポーネントがありますし、また Qt Components というプロジェクトで整備を開始しています。このプロジェクトに関しては詳しくは「未来の創造: Qt Quick Components の(再)紹介」を参照してください。これらのコンポーネントをインポートすればもっと簡易にボタン等を作成することができるようになると思われます。

次回は今回作成したボタンを使用して画像の移動を行ってみようと考えています。


Blog Topics:

Comments