Qtブログ(日本語)

提案: Qt Quick デザイナのワークフロー

作成者: 朝木卓見|Aug 9, 2011 6:38:43 AM

この記事は Qt Blog の "Proposal: Qt Quick Designer Workflow" を翻訳したものです。
執筆: Marco Bubke, 2011年8月3日

従来のウィジェットベースの Qt デザイナは宣言型のフォームと命令型のロジックを明確に区別するように作られています。デザインされた宣言型のフォームは .ui ファイルに格納されます。

QML では宣言型のコードと命令型のコードが簡単に混ざります。(視覚的効果をもたらす)命令型のコードを QML ファイルに追加すると、もうそれは純粋な宣言型ではありませんし、ビジュアルエディタでの見た目とは異なるものになるでしょう。ビジュアルエディタではテキストでの記述を視覚的な記述に翻訳する方法が必要です。通常、命令型のコードではそれは不可能ですし、Qt Quick デザイナでは試みようともしていません。

以下のコードはビジュアルエディタでは扱いにくい例です。

Item {
width: 800
height: 600
Rectangle {
id: rectangle
width: 100
height: 100
}
Component.onCompleted: center(rectangle)
}

Component.onCompleted は一度しか呼ばれないのに対して、Qt Quick デザイナでは幅や高さが何度も変わることがあります。どうやってそれに対応すれば良いのでしょうか。ビジュアルエディタで変更があるたびに Component.onCompleted を呼ぶべきでしょうか。center 関数の場合には問題ないでしょうが、オブジェクトの生成が含まれている場合にはどうでしょうか。変更のたびに全体を再構成するという手はありますが、それでは編集の反応が遅くなって生産性のある仕事は行えないでしょう。

center 関数は座標の変換を行います。どうすればビジュアルエディタは center 関数が座標の変換を行うことを知ることができるでしょうか。それにはコードの意図を理解する必要がありますが、通常ビジュアルエディタにはそれはできません。そのため、Qt Quick デザイナではハンドラやスクリプトを無視することにしました。

バインディングは宣言型ですので、ビジュアルエディタはその評価は行います。しかし、それでもバインディングを一切「理解」していません。ビジュアルエディタにとってバインディングはブラックボックスです。

ハンドラやスクリプトに重度に依存するファイルを開く場合、スクリプトで見た目を変更しているとビジュアルエディタとアプリケーションでは表示が異なります。このようなケースではビジュアルエディタを最大限に活用することはできません。

もう一つの側面は一般的なワークフローです。従来の ui ファイルでの手法のように、デザインとコードを完全に分離したい方々もいらっしゃると思います。幸運なことに QML ではそれは可能なのですが、強制はしません。すなわち、どの手法を選択するかは QML のユーザに委ねられているのです。

そこで、我々は検討を重ねて以下のアイデアを思いつきました。QML でデザインとロジックをどうやって分離するかの例を示します。最初のファイルはビジュアルエディタで、次のファイルはテキストエディタで編集しました。このように、再び宣言型のフォームと命令型のロジックをきれいに分けることができます。

CalculatorPage_ui.qml

import QtQuick 1.0
import com.nokia.symbian 1.0

Page {
id: calculatorPage

property Item button: button

Button {
id: button
x: 0
y: 195
width: 80
height: 80
text: "1"
}

states: [
State {
name: "horizontal"
when: screen.currentOrientation == Screen.Landscape

PropertyChanges {
target: button
x: 87
y: 45
}
}
]
}

CalculatorPage.qml

import QtQuick 1.0
import "calculator.js" as Calculator

CalculatorPage_ui {
Connections {
target: button
onClicked: Calculator.appendSign("1")
}
}

全ての宣言型の項目に関しては ui ファイルに記述して、それを命令型ロジックを記載したファイルから利用することができます。内部オブジェクトにアクセスするには、property Item itemId: itemId という書式でエクスポートしなくてはいけません(訳注: 上記のサンプルでは CalculatorPage_ui.qml の7行目)。ロジックファイルでは [qml Connections] を使ってオブジェクトにハンドラを追加します。

このアイデアをどう思いますか。皆さんの意見がとても重要です。
(訳注: 元の記事 へのフィードバックをお願いします。)

簡単なサンプルアプリケーションのダウンロード