プロパティエイリアス
属性エイリアスは、別の属性への参照を保持する属性です。属性に新しい一意のストレージスペースを割り当てる通常の属性定義とは異なり、属性エイリアスは、新しく宣言された属性(エイリアス属性と呼ばれる)を既存の属性(エイリアス属性)への直接参照として接続します。
属性エイリアス宣言は通常の属性定義のように見えますが、属性タイプの代わりにエイリアスキーワードが必要であり、属性宣言の右側は有効なエイリアス参照である必要があります。
[デフォルト]プロパティエイリアス<名前>:<エイリアス参照>
通常の属性とは異なり、エイリアスには次の制限があります。
・エイリアスが宣言されている型のスコープ内のオブジェクトまたはオブジェクトのプロパティのみを参照できます。
・任意のJavaScript式を含めることはできません
・型の範囲外で宣言されたオブジェクトを参照することはできません。
・オプションのデフォルト値を持つ通常のプロパティとは異なり、エイリアス参照は選択できません。エイリアスを最初に宣言するときに、エイリアス参照を指定する必要があります。
・追加の属性を参照することはできません。
•それは深い参照することはできません3以上の階層内の属性の程度を。次のコードは機能しません。
プロパティエイリアスの色:myItem.myRect.border.color Item { id:myItem property Rectangle myRect }
ただし、最大2レベルの属性エイリアスを使用できます。
プロパティエイリアスcolor:rectangle.border.color Rectangle { id:rectangle}
たとえば、次は、Textサブテキストオブジェクトのオブジェクトに接続されている、buttonTextのエイリアスプロパティを持つボタンのタイプです。
// Button.qml import QtQuick 2.0 Rectangle { property alias buttonText:textItem.text width:100; 高さ:30; color: "yellow" Text {id:textItem}}
次のコードは、Buttonの子Textオブジェクトに定義されたテキスト文字列を作成します。
ボタン{buttonText: "Click Me"}
ここで、buttonTextを変更すると、textItem.textの値が直接変更されます。他の値は変更されず、textItem.textが更新されます。buttonTextがエイリアスでない場合、プロパティバインディングは双方向ではないため、その値を変更しても実際に表示されるテキストはまったく変更されません。buttonTextがtextItem.textを変更すると、値は変更されますが、それ以外の場合は変更されません。
プロパティエイリアスに関する注意
エイリアスは、コンポーネントが完全に初期化された後にのみアクティブ化できます。初期化されていないエイリアスが参照されると、エラーが生成されます。同様に、alias属性にエイリアスを設定すると、エラーが発生します。
プロパティエイリアスwidgetLabel:label //エラーを生成します//widgetLabel.text: "初期テキスト" //エラーを生成します//プロパティエイリアスwidgetLabelText:widgetLabel.text Component.onCompleted:widgetLabel.text = "Alias completed Initialization"
ただし、ルートオブジェクトに属性エイリアスを持つQMLオブジェクトタイプをインポートすると、その属性は通常のQt属性として表示されるため、エイリアス参照で使用できます。
エイリアス属性は既存の属性と同じ名前を持つことができ、それにより既存の属性を効果的に上書きします。たとえば、次のQMLタイプには、組み込みのRectangle :: color属性と同じ名前のcolorエイリアス属性があります。
Rectangle { id:colorrectangle property alias color:bluerectangle.color color: "red" Rectangle { id:bluerectangle color: "#1234ff" } Component.onCompleted:{ console.log(coloredrectangle.color)// prints "#1234ff" setInternalColor () console.log(coloredrectangle.color)//「#111111」を 出力しますcolorrectangle.color = "#884646" console.log(coloredrectangle.color)//#884646を出力します } //内部プロパティ 関数にアクセスできる内部関数setInternalColor(){ color = "#111111" }}
このタイプを使用し、そのcolor属性を参照するオブジェクトは、通常のRectangle :: color属性ではなく、エイリアスを参照します。ただし、内部的には、長方形はその色属性を正しく設定し、エイリアスではなく実際に定義された属性を参照できます。
プロパティのエイリアスとタイプ
属性エイリアスは、明示的な型指定を持つことができません。属性エイリアスのタイプは、それが参照する属性またはオブジェクトの宣言されたタイプです。したがって、idによって参照されるオブジェクトのエイリアスを作成し、インラインで宣言された他の属性を使用する場合、エイリアスを通じてこれらの追加の属性にアクセスすることはできません。
// MyItem.qml Item { property alias inner:innerItem Item { id:innerItem property int extraProperty }} innerは単なるアイテムであるため、このコンポーネントの外部からinner.extraPropertyを初期化することはできません 。// main.qmlMyItem { inner.extraProperty:5 / /失敗}
ただし、専用の.qmlファイルを使用して内部オブジェクトを個別のコンポーネントに抽出する場合は、コンポーネントをインスタンス化して、エイリアスを通じてそのすべてのプロパティを使用できます。
// MainItem.qml Item { // innerがExtraItem プロパティエイリアスinnerになったため、inner.extraPropertyにアクセスできるようになりますinner:innerItem ExtraItem { id:innerItem } } // ExtraItem.qml Item { property int extraProperty }
デフォルトの属性
オブジェクト定義にはデフォルト属性を設定できます。デフォルト属性は、オブジェクトが別のオブジェクトの定義で宣言されているが、特定の属性の値として宣言されていない場合に値が割り当てられる属性です。
オプションのdefaultキーワードを使用して属性を宣言すると、デフォルトの属性としてマークされます。たとえば、デフォルトのプロパティが設定されたファイルMyLabel.qml someTextがあるとします。
// MyLabel.qml import QtQuick 2.0 Text { default property var someText text: "Hello、" + someText.text }
someText値は、MyLabelオブジェクト定義で次のように割り当てることができます。
MyLabel { Text {text: "world!" }}
次と同じ:
MyLabel { someText:Text {text: "world!" }}
ただし、someTextプロパティはデフォルトプロパティとしてマークされているため、このプロパティにTextオブジェクトを明示的に割り当てる必要はありません。
childプロパティに明示的に追加しなくても、子オブジェクトをItemベースのタイプに追加できることがわかります。これは、アイテムのデフォルト属性がデータ属性であり、このリストに追加されたアイテムはすべて、リスト内の子オブジェクトに自動的に追加されるためです。
デフォルトの属性は、アイテムをアイテムに再割り当てするのに役立ちます。デフォルトプロパティを使用してTabWidgetの子を内部ListViewの子に自動的に再割り当てするTabWidgetの例を参照してください。
読み取り専用属性
オブジェクト宣言では、readonlyキーワードを使用して、次の構文で読み取り専用属性を定義できます。
readonlyプロパティ<propertyType> <propertyName>:<initialValue>
初期化中に、値を読み取り専用属性に割り当てる必要があります。読み取り専用属性が初期化されると、命令コードまたは他の手段から値を割り当てることができなくなります。
たとえば、Component.onCompleted次のブロックのコードは無効です。
Item { readonly property int someNumber:10 Component.onCompleted:someNumber = 20 //機能せず、エラーが発生します} 注:読み取り専用プロパティをデフォルトプロパティにすることもできません。
プロパティ修飾子オブジェクト
属性には、属性値修飾子オブジェクトが関連付けられている場合があります。特定の属性に関連付けられた属性修飾子タイプのインスタンスを宣言する構文は、次のとおりです。
<PropertyModifierTypeName> on <propertyName> { //オブジェクトインスタンスの属性 }
上記の構文は、実際には既存のプロパティに作用するオブジェクトをインスタンス化するオブジェクト宣言であることに注意してください。
一部の属性修飾子タイプは特定の属性タイプにのみ適用される場合がありますが、これは言語によって強制されていません。たとえば、NumberAnimationによって提供されるQtQuickタイプは、数値タイプ(intやrealなど)のプロパティのみをアニメーション化します。非数値プロパティでNumberAnimationを使用しようとしても、エラーは発生しませんが、非数値プロパティはアニメーション化されません。特定の属性タイプに関連付けられているときの属性修飾子タイプの動作は、その実装によって定義されます。
信号のプロパティ
信号は、プロパティの変更、アニメーションの開始または停止、画像のダウンロードなど、特定のイベントが発生したことを示すオブジェクトからの通知です。たとえば、マウス領域タイプでは、マウス領域をクリックしたときに発生するユーザークリック信号があります。
特定のシグナルが発行されるときはいつでも、オブジェクトはシグナルハンドラーを介して通知されます。<Signal>構文で使用して、シグナルハンドラーを宣言します。<Signal>は、最初の文字を大文字にしたシグナル名です。シグナルハンドラーは、シグナルを発信するオブジェクトの定義内で宣言する必要があり、ハンドラーには、シグナルハンドラーが呼び出されたときに実行されるJavaScriptコードブロックが含まれている必要があります。
たとえば、次のonClickedシグナルハンドラーは、MouseAreaオブジェクト定義で宣言され、MouseAreaがクリックされたときに呼び出され、コンソールメッセージが出力されます。
QtQuick 2.0 アイテムのインポート{ 幅:100; 高さ:100 MouseArea { anchors.fill:parent onClicked:{ console.log( "Click!") } }}
信号プロパティを定義する
クラスのQ_SIGNALを登録してQML型システムに登録することにより、C ++で型の信号を定義できます。または、次の構文を使用して、QMLドキュメントのオブジェクト宣言でオブジェクトタイプのカスタム信号を定義できます。
シグナル<signalName> [([<type> <parameter name> [、...]])]
同じ型ブロックで同じ名前の2つの信号またはメソッドを宣言しようとすると、エラーになります。ただし、新しい信号は既存の信号の名前をtypeで再利用できます。(既存のシグナルが非表示になり、アクセスが困難になる可能性があるため、これは注意して行う必要があります。)
これらは、シグナル宣言の3つの例です。
QtQuick 2.0 アイテムのインポート{ シグナルがクリックされた シグナルhovered () シグナルactionPerformed(string action、var actionResult)}
信号にパラメーターがない場合、「()」ブラケットはオプションです。パラメータを使用する場合は、上記の信号actionPerformedのstringおよびvarパラメータなどのパラメータタイプを宣言する必要があります。許可されるパラメータタイプは、このページの「プロパティプロパティの定義」にリストされているものと同じです。
通知するには、それをメソッドとして呼び出します。シグナルが発行されると、関連するシグナルハンドラーが呼び出され、ハンドラーは定義されたシグナルパラメーター名を使用して対応するパラメーターにアクセスできます。
プロパティ変更信号
QMLタイプは、プロパティプロパティのセクションで前述したように、プロパティ値が変更されるたびに発行される組み込みのプロパティ変更信号も提供します。これらの信号が役立つ理由とその使用方法の詳細については、プロパティ変更信号ハンドラーに関する次のセクションを参照してください。
シグナルハンドラーのプロパティ
シグナルハンドラーは特別なメソッド属性であり、関連するシグナルが発行されている限り、QMLエンジンはメソッドの実装を呼び出します。QMLのオブジェクト定義にシグナルを追加すると、関連するシグナルハンドラーがオブジェクト定義に自動的に追加されます。これはデフォルトでは空です。お客様は、プログラムロジックを実装するための実装を提供できます。
以下のSquareButton.qmlファイルで定義されている以下のSquareButtonタイプについて考えてみます。信号がアクティブ化および非アクティブ化されています。
// SquareButton.qml Rectangle { id:root signalactivated(real xPosition、real yPosition) signal deactivated property int side:100 width:side; 高さ:サイド MouseArea { anchors.fill:parent onPressed:root.activated(mouse.x、mouse.y) onReleased:root.deactivated() }}
これらの信号は、SquareButtonの同じディレクトリにある別のQMLファイル内の任意のオブジェクトで受信できます。信号ハンドラーの実装は、クライアントによって提供されます。
// myapplication.qml SquareButton { onActivated:console.log( "Activated at" + xPosition + "、" + yPosition) onDeactivated:console.log( "Deactivated!")}
シグナルの使用の詳細については、シグナルおよびハンドラーイベントシステムを参照してください。
プロパティ変更シグナルハンドラー
プロパティ変更信号のシグナルハンドラーは、on <Property> Changedの構文形式を採用しています。ここで、<Property>は最初の文字を大文字にしたプロパティの名前です。たとえば、TextInputタイプのドキュメントはtextChangedシグナルを記録しませんが、TextInputにはテキストプロパティがあるため、シグナルは暗黙的に使用可能であり、このプロパティが変更されている限り、呼び出されるシグナルハンドラーを作成できます。
QtQuick 2.0 TextInputをインポートする{ text: "これを変更!" onTextChanged:console.log( "Text has changed to:"、text)}
メソッド属性
オブジェクト型メソッドは、特定の処理を実行したり、他のイベントをトリガーしたりするために呼び出すことができる関数です。メソッドをシグナルに接続して、シグナルが発行されたときにメソッドが自動的に呼び出されるようにすることができます。詳細については、シグナルおよびハンドラーイベントシステムを参照してください。
メソッド属性を定義する
C ++で型のメソッドを定義するには、クラスの関数をマークし、Q_INVOKABLEを使用してQML型システムにクラスを登録するか、クラスのQ_SLOTとして登録します。または、次の構文を使用して、QMLドキュメントのオブジェクト宣言にカスタムメソッドを追加できます。
function <functionName>([<parameterName> [、...]]){<body>}
メソッドをQMLタイプに追加して、独立した再利用可能なJavaScriptコードブロックを定義できます。これらのメソッドは、内部または外部オブジェクトで呼び出すことができます。
シグナルとは異なり、メソッドのパラメーター型はデフォルトでvar型になるため、宣言する必要はありません。
同じ型ブロックで同じ名前の2つのメソッドまたはシグナルを宣言しようとすると、エラーになります。ただし、新しいメソッドは、型の既存のメソッドの名前を再利用できます。(既存のメソッドが非表示になり、アクセスできなくなる可能性があるため、これは注意して行う必要があります。)
以下は、値が高さに割り当てられたときに呼び出されるcalculateHeight()メソッドを含むRectangleです。
import QtQuick 2.0 Rectangle { id:rect function calculateHeight(){ return rect.width / 2; } 幅:100 高さ:calculateHeight() }
メソッドにパラメーターがある場合、メソッド内で名前を使用してパラメーターにアクセスできます。以下では、MouseAreaをクリックすると、moveTo()メソッドが呼び出され、メソッドはnewXからnewYパラメータの受信と、テキストを再配置するためのパラメータを参照できます。
QtQuick 2.0 アイテムのインポート{ 幅:200; 高さ:200 MouseArea { anchors.fill:parent onClicked:label.moveTo(mouse.x、mouse.y) } Text { id:label function moveTo(newX、newY){ label.x = newX; label.y = newY; } テキスト:「私を動かして!」 }}
追加の属性と追加のシグナルハンドラー
追加の属性と追加のシグナルハンドラーは、オブジェクトが他の属性またはシグナルハンドラーで注釈を付けることができるメカニズムであり、追加の属性またはシグナルハンドラーはオブジェクトで使用できません。特に、これらのオブジェクトにより、単一のオブジェクトに特に関連するプロパティまたは信号にオブジェクトがアクセスできるようになります。
QMLタイプの実装では、C ++で特定のプロパティとシグナルを使用して追加のタイプを作成することを選択できます。次に、このタイプのインスタンスを作成して、実行時にそれらを特定のオブジェクトにアタッチし、それらのオブジェクトが追加のタイプの属性と信号にアクセスできるようにします。追加のタイプの名前をプレフィックスとして付けることにより、属性と対応するシグナルハンドラーにアクセスします。
追加の属性およびハンドラーへの参照の構文は次のとおりです。
<AttachingType>。<propertyName>
<AttachingType> .on <SignalName>
たとえば、ListViewの型には、ListView.isCurrentItemという追加のプロパティがあり、各デリゲートオブジェクトのListViewで使用できます。個々のデリゲートオブジェクトは、それを使用して、ビューで現在選択されているアイテムかどうかを判断できます。
QtQuick 2.0 ListViewをインポートする{ 幅:240; 高さ:320 モデル:3 デリゲート:長方形{ 幅:100; 高さ:30 色:ListView.isCurrentItem?"赤": "黄" }}
この場合、追加のタイプの名前はListViewで、関連するプロパティはisCurrentItemであるため、追加のプロパティはListView.isCurrentItemと呼ばれます。
追加のシグナルハンドラーも同じ方法で参照されます。たとえば、コンポーネントの作成プロセスが完了した後、通常、Component.onCompletedを使用していくつかのシグナルハンドラーをアタッチし、JavaScriptコードを実行します。次の例では、ListModelが完全に作成されると、Component.onCompletedは自動的にそのシグナルハンドラーを呼び出してモデルに入力します。
QtQuick 2.0 ListViewをインポートする{ 幅:240; 高さ:320 モデル:ListModel { id:listModel Component.onCompleted:{ for(var i = 0; i <10; i ++) listModel.append({"Name": "Item" + i}) } } デリゲート:テキスト{テキスト:インデックス}}
追加のタイプの名前はComponentであり、タイプには完全なシグナルがあるため、追加のシグナルハンドラーはComponent.onCompletedと呼ばれます。
追加のプロパティおよびシグナルハンドラーへのアクセスに関する注意点
よくある間違いは、追加のプロパティとシグナルハンドラーが、これらのプロパティがアタッチされているオブジェクトの子から直接アクセスできると想定することです。これはそうではありません。追加タイプのインスタンスは特定のオブジェクトにのみアタッチされ、オブジェクトとそのすべてのサブオブジェクトにはアタッチされません。
たとえば、以下は、添付属性を含む前の例の変更バージョンです。今回は、手数料はプロジェクトであり、色付きの長方形はプロジェクトのサブアイテムです。
QtQuick 2.0 ListViewをインポートする{ 幅:240; 高さ:320 モデル:3 デリゲート:アイテム{ 幅:100; 高さ:30 長方形{ 幅:100; 高さ:30 色:ListView.isCurrentItem?"赤": "黄" //間違い!これは機能しません。 } }}
ListView.isCurrentItemはルートデリゲートオブジェクトにのみアタッチされ、子オブジェクトにはアタッチされないため、これは期待どおりに機能しません。Rectangleはデリゲート自体ではなくデリゲートの子であるため、フォームのisCurrentItem追加プロパティListView.isCurrentItemにアクセスできません。したがって、長方形にはルートデリゲートを介してisCurrentItemでアクセスする必要があります。
ListView { // .... delegate:Item { id:delegateItem width:100; 高さ:30 長方形{ 幅:100; 高さ:30 色:delegateItem.ListView.isCurrentItem?"red": "yellow" //正しい } }}
delegateItem.ListView.isCurrentItemは、isCurrentItemによって委任された追加のプロパティを正しく参照するようになりました。
列挙プロパティ
列挙は、名前付けオプションの固定セットを提供します。enumキーワードを使用して、これらをQMLで宣言できます。
// MyText.qmlText { enum TextType { Normal、 Heading }}
上記のように、列挙型(TextTypeなど)と値(Normalなど)は大文字で始める必要があります。
<Type>。<EnumerationType>。<Value>または参照値<Type>。<Value>を渡します。
// MyText.qmlText { enum TextType { Normal、 Heading } property int textType:MyText.TextType.Normal font.bold:textType == MyText.TextType.Heading font.pixelSize:textType == MyText.TextType.Heading?24:12}
QMLでの列挙型の使用の詳細については、QML基本型列挙型のドキュメントをご覧ください。
Qt 5.10では、QMLで列挙型を宣言する機能が導入されました。