Qt6 QML 和訳文書 P102~P114
Layout Items
「QMLはアンカーを使って柔軟な方法をレイアウトアイテムへ提供します。アンカーのコンセプトはアイテムを基本としていて、全ての可視QML要素で利用可能です。アンカーは契約のように動き、①競合しているジオメトリよりも強いのです。②アンカーは相対性の式です。あなたは常にアンカーを付ける相対的な要素を必要とします。」
①geometryで、可視要素は位置とサイズを決定できますが、この「位置決め」という点では、アンカーレイアウトの機能と競合関係になります。その時、どちらが優先されるかというと、アンカーレイアウトの機能が優先されるということです。
②アンカーは、ただ一つの可視要素だけがあるのでは機能しません。他の可視要素があり、それとの関係でどの位置にあるのか?ということを問題にします。それが、「あなたは常にアンカーを付ける相対的な要素を必要とします。」の意味です。
「ある要素は6つの主なアンカーラインを持ちます。(top, bottom, left, right, horizontalCenter, verticalCenter).加えて、Text要素にはテキストのためのベースラインアンカーがあります。①それぞれのアンカーラインはオフセットを持ちます。top, bottom, left,そしてrightアンカーの場合、それらはmarginsと呼ばれます。horizontalCenter, verticalCenter、そしてbaselineに対しては、それらはオフセットと呼ばれます。」
①アンカーラインのオフセットは、top, bottom, left, rightの場合は、marginsと呼ばれ、horizontalCenter, verticalCenter, baselineの場合は、オフセットと呼ばれるようです。2つの名前があります。
ある要素は親要素を上塗りします。
GreenSquare {
BlueSquare {
width: 12
anchors.fill: parent
anchors.margins: 8
text: '(1)'
}
}
ある要素は親要素の左側に並びます。
GreenSquare {
BlueSquare {
width: 48
y: 8
anchors.left: parent.left
anchors.leftMargin: 8
text: '(2)'
}
}
ある要素の左側は、親の右側に並びます。
GreenSquare {
BlueSquare {
width: 48
anchors.left: parent.right
text: '(3)'
}
}
「中央に並べられた要素。青1は親の上に水平、中心に位置づけられます。青2も同様に親の上に水平、中心ですが、青1では、その上部は、青2の上部は、青1の底のラインに並べられます。」
GreenSquare {
BlueSquare {
id: blue1
width: 48; height: 24
y: 8
anchors.horizontalCenter: parent.horizontalCenter
}
BlueSquare {
id: blue2
width: 72; height: 24
anchors.top: blue1.bottom
anchors.topMargin: 4
anchors.horizontalCenter: blue1.horizontalCenter
text: '(4)'
}
}
ある要素は親要素の中央に置かれます。
GreenSquare {
BlueSquare {
width: 48
anchors.centerIn: parent
text: '(5)'
}
}
「ある要素は水平そして垂直の中央のラインを使って、親要素上の左オフセット込みで中心に置かれます。」
GreenSquare {
BlueSquare {
width: 48
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -12
anchors.verticalCenter: parent.verticalCenter
text: '(6)'
}
}
Hidden Gems
私たちの四角形は魔法であるかのようにドラッグを可能にするよう、性能を向上しました。エグザンプルを試してみてください。そして、いくつかの四角形の周りでドラッグをしてみてください。あなたは、(1)(アンカーが全くないので、(1)の親をドラッグすることはできるけれども、全てのサイドでアンカーされているので、ドラッグはできない事がわかります。(2)は垂直にドラッグできます。左側だけが固定されているからです。同じことは(3)にあてはまります。(4)は垂直にのみドラッグでき、四角形は水平に中央につけます。(5)は親の中心にあり、そしてその通り、ドラッグできません。同じことは(6)にも当てはまります。要素をドラッグすることはそのx,yの位置を変化させるという意味です。アンカーはx,yのプロパティを設定することよりも強力で、ドラッグがアンカーのラインによって制限されます。私たちが後でアニメーションについて話をする時に、この効果が実感できます。
Input Elements
私たちはマウス入力の要素としてMouseAreaを使いました。次に、私たちはキーボード入力に焦点を当てます。私たちはテキスト編集要素:TextInputとTextEditで始めます。
TextInput
TextInputはユーザーが一行のテキストを入力できるものです。要素は例えば、validator,inputMask,そしてechoModeのようなもので、入力の制限もサポートしています。
// textinput.qml
import QtQuick
Rectangle {
width: 200
height: 80
color: "linen"
TextInput {
id: input1
x: 8; y: 8
width: 96; height: 20
focus: true
text: "Text Input 1"
}
TextInput {
id: input2
x: 8; y: 36
width: 96; height: 20
text: "Text Input 2"
}
}
「ユーザーはTextInput内で、フォーカスを変更するためにクリックできます。フォーカスをキーボードで切り替えるのをサポートするためには、KeyNavigationが付け加えられたプロパティを使うことができます。」
// textinput2.qml
import QtQuick
Rectangle {
width: 200
height: 80
color: "linen"
TextInput {
id: input1
x: 8; y: 8
width: 96; height: 20
focus: true
text: "Text Input 1"
KeyNavigation.tab: input2
}
TextInput {
id: input2
x: 8; y: 36
width: 96; height: 20
text: "Text Input 2"
KeyNavigation.tab: input1
}
}
「KeyNavigationの添付プロパティはid要素が指定されたkey pressにフォーカスを切り替えるためにバウンドされるナビゲーションキーのプリセットをサポートします。テキスト入力要素は点滅するカーソルと入力されたテキストのほかに、不可視要素を持ちます。ユーザーが入力要素として要素を認識することができるために、いくつかの可視装飾を必要とします。例えば、単純な矩形です。TextInputを要素内に置くとき、あなたは他のプロパティがアクセスできるようになってほしい主なプロパティをエクスポートすることを確認する必要が合います。私たちは一片のコードをTLineEditV1と呼ばれる独自のコンポーネントへ再利用のために移動させます。」
// TLineEditV1.qml
import QtQuick
Rectangle {
width: 96; height: input.height + 8
color: "lightsteelblue"
border.color: "gray"
property alias text: input.text
property alias input: input
TextInput {
id: input
anchors.fill: parent
anchors.margins: 4
focus: true
}
}
TIP
Rectangle {
...
TLineEditV1 {
id: input1
...
}
TLineEditV1 {
id: input2
...
}
}
ナビゲーションのためのタブキーを試してください。フォーカスはinput2を変化させないということが体験できます。単にfocus: trueの使用だけでは十分ではありません。問題はフォーカスがinput2要素に行こうする時、TlineEditV1(矩形)内のトップレベルのアイテムはフォーカスを受け取り、そしてフォーカスをTextInputへ進めないことです。これを防ぐためには、QMLはFocusScopeを提供します。
FocusScope
フォーカススコープはfocus: trueでフォーカススコープがフォーカスを受け取る時、そのフォーカスを受け取る最後の子要素を宣言します。だから、フォーカスをフォーカスを要求している最後の子要素へ進めます。私たちはルート要素としてフォーカススコープを使い、TLineEditV2というTLineEditコンポーネントの第2のバージョンを作ります。
// TLineEditV2.qml
import QtQuick
FocusScope {
width: 96; height: input.height + 8
Rectangle {
anchors.fill: parent
color: "lightsteelblue"
border.color: "gray"
}
property alias text: input.text
property alias input: input
TextInput {
id: input
anchors.fill: parent
anchors.margins: 4
focus: true
}
}
Our example now looks like this:
Rectangle {
...
TLineEditV2 {
id: input1
...
}
TLineEditV2 {
id: input2
...
}
}
今やタブキーを押すと、二つのコンポーネント間でフォーカスを切り替えることができ、コンポーネント内の現在の子要素がフォーカスされます。
TextEdit
// TTextEdit.qml
import QtQuick
FocusScope {
width: 96; height: 96
Rectangle {
anchors.fill: parent
color: "lightsteelblue"
border.color: "gray"
}
property alias text: input.text
property alias input: input
TextEdit {
id: input
anchors.fill: parent
anchors.margins: 4
focus: true
}
}
// textedit.qml
import QtQuick
Rectangle {
width: 136
height: 120
color: "linen"
TTextEdit {
id: input
x: 8; y: 8
width: 120; height: 104
focus: true
text: "Text Edit"
}
}
Keys Element
// keys.qml
import QtQuick
DarkSquare {
width: 400; height: 200
GreenSquare {
id: square
x: 8; y: 8
}
focus: true
Keys.onLeftPressed: square.x -= 8
Keys.onRightPressed: square.x += 8
Keys.onUpPressed: square.y -= 8
Keys.onDownPressed: square.y += 8
Keys.onPressed: function (event) {
switch(event.key) {
case Qt.Key_Plus:
square.scale += 0.2
break;
case Qt.Key_Minus:
square.scale -= 0.2
break;
}
}
}