QMLオブジェクトのプロパティ
各QMLオブジェクトタイプは、一連のプロパティを定義します。オブジェクトタイプのインスタンスが作成されるたびに、インスタンスのこれらの属性も自動的に作成されます。次に、いくつかの異なるタイプの属性について説明します。
id属性
各QMLオブジェクトタイプには、一意に決定されるid属性があります。この属性はQML言語自体によって提供され、QMLオブジェクトタイプで再定義およびオーバーロードすることはできません。
id属性の値を指定して、オブジェクトを一意に識別し、他のオブジェクトが参照できるようにする必要があります。Id属性の値は小文字またはアンダースコアで始まる必要があり、文字、数字、アンダースコアなどの文字のみを含めることができます。
以下は、TextInputオブジェクトとTextオブジェクトです。TextInputオブジェクトのidプロパティは「myTextInput」です。Textオブジェクトのtextプロパティ値は、myTextInput.textを介してTextInputオブジェクトのtextプロパティ値と同じに設定されます。
後でコンポーネントの可視ドメインのid属性を通じてオブジェクトを参照できます。したがって、id属性値は、コンポーネントの可視ドメイン内で一意である必要があります。
オブジェクトインスタンスが作成されると、id属性値は変更できません。Id属性は通常の属性のように見えますが、実際の通常の属性ではありません。たとえば、上記の例では、myTextInput.idを使用できません。
プロパティ属性は、
プロパティは、オブジェクトのプロパティは、静的な値に割り当てられ又は動的式に結合することが可能です。プロパティの値は、他のオブジェクトから読み取ることができます。一般に、QMLタイプがプロパティプロパティを変更できないことを明示的に指定しない限り、プロパティプロパティは他のオブジェクトによっても変更できます。
[プロパティプロパティの定義]
プロパティプロパティはC ++で定義し、Q_PROPERTYを介してQML型システムに登録できます。もちろん、次の構文を使用して、QMLドキュメント内のオブジェクトのプロパティプロパティをカスタマイズすることもできます。
このようにして、オブジェクトは特定の値を他のオブジェクトに公開することができます。
プロパティの名前は小文字で始める必要があり、文字、数字、アンダースコアのみを含めることができます。JavaScriptの予約済みキーワードは、プロパティ属性の名前として使用できません。Defaultキーワードはオプションであり、defaultおよびdefaultプロパティ修飾子の詳細は後で説明します。
カスタムプロパティプロパティを定義すると、プロパティプロパティの値変更信号が暗黙的に作成されます。これは、<PropertyName> Changedで指定されたシグナルハンドラーに関連付けられています。<PropertyName>はプロパティの名前で、最初の文字は大文字にする必要があります。
例:次の例では、2つのプロパティプロパティを定義し、そのシグナルハンドラを実装しています。
[法的タイプのカスタムプロパティ属性]
QML基本タイプの列挙型は、カスタムプロパティ属性タイプとして使用できます。例:以下はすべて有効なプロパティ属性宣言です。
QtQuickモジュールによって提供されるいくつかの基本的なタイプは、QtQuickモジュールがQMLドキュメントにインポートされない限り、プロパティタイプとして使用できません。
varの基本的なタイプは一般的なタイプであり、リストやオブジェクトなど、あらゆるタイプの値を保存できます。
さらに、任意のQMLオブジェクトタイプをプロパティ属性タイプとして使用できます。たとえば、次のとおりです。
これは、カスタムQMLタイプにも適用されます。QMLタイプがColorfulButton.qmlファイルで定義されている場合、ColorfulButtonタイプのpropertyプロパティも有効です。
【法的性質値】
定義済みのプロパティ属性に値を割り当てるには、次の2つの方法があります。
*初期化
*割り当て
値は、静的な値またはバインディング式にすることができます。
{初期化}
プロパティプロパティの初期化:
プロパティプロパティを定義するときに割り当てを初期化することもできます。
初期割り当ての例は次のとおりです。
{割り当て}
JavaScriptコードを使用して、次のようにプロパティ属性に値を割り当てることができます。
次に例を示します。
【法的性質値】
前述のように、静的属性とバインディング式の2種類の値をプロパティ属性に割り当てることができます。
例:
多くの場合、QMLは文字列型から他の型への変換を提供するため、文字列型の値は多くの異なる型の値に自動的に変換できます(これが、「赤い」値をcolor属性に割り当てることができる理由です)。
式にバインドする場合、右側の式は適切な値の型を返すQt.binding()関数の値を返す必要があることに特に注意する必要があります。プロパティプロパティの初期化時に式を直接割り当てることができ、その関数を使用する必要はありません(実際、関数を使用するとエラーも発生します)。
【タイプセーフ】
属性はすべてタイプセーフです。属性に割り当てられる値は、タイプと一致する必要があります。
たとえば、次の割り当てではエラーが発生します。
実行時にプロパティに誤った値が割り当てられると、割り当ては成功せず、エラーが生成されます。
前述のように、一部の属性タイプには値を表現するための適切なタイプがないため、現時点では、QMLエンジンが適切な文字列タイプ変換を提供します。例:color属性。この属性に格納される値の型は、文字列型ではなく色型である必要がありますが、エラーなしで文字列型の値を割り当てることができます。
【特別物件属性タイプ】
オブジェクトリストタイプのプロパティプロパティ
Listタイプのpropertyプロパティには、QMLオブジェクトタイプリストの値を割り当てることもできます。割り当ての形式は次のとおりです。
たとえば、項目タイプには状態属性があり、これを使用して状態オブジェクトタイプのリストを保存できます。次のコードを使用して、リストを初期化します。
リストに項目が1つしかない場合は、角括弧を省略できます。
オブジェクトリストタイプのプロパティプロパティを次のように定義できます。
リスト型プロパティ宣言の例は次のとおりです。
リストの値を格納するためのプロパティを宣言したいが、QMLオブジェクトタイプの値を格納する必要はない場合は、varのプロパティプロパティを宣言する必要があります。
[グループ化されたプロパティ]
場合によっては、ロジックに従って属性をサブ属性グループに分割できます。これらのサブ属性は、「。」またはグループによって割り当てることができます。
例:テキストタイプにはフォントグループ属性があります。次の例では、最初のTextオブジェクトは「。」を使用してフォントの値を初期化し、2番目のオブジェクトはグループを使用して値を割り当てます。
グループ属性タイプはすべて基本タイプです。これらの基本的な型の一部はQML言語によって提供され、他の部分はQt Quickモジュールによって提供されます。
【属性エイリアス】
属性エイリアスは、別の属性への参照を保存することです。共通属性の定義とは異なり、共通属性の定義には、新しい一意のストレージスペースを割り当てる必要があり、属性エイリアスは属性に接続されるだけです。
属性エイリアスの定義ルート属性定義も同様ですが、属性エイリアスでは、属性定義のプロパティタイプの代わりにaliasキーワードを使用する必要があります。右側の値は有効な参照エイリアスである必要があります。
通常の属性とは異なり、エイリアスはオブジェクトまたはオブジェクトの属性のみを参照できます。
例:次のButtonタイプにはbuttonTextプロパティのエイリアスがあり、子Textオブジェクトのtextプロパティにリンクされています。
次のコードは、ボタンを作成し、テキスト文字列を定義します。
buttonTextを変更し、textItem.textの値を直接変更します。他の値は変更しません。buttonTextが属性エイリアスではない場合、その値を変更しても、表示されるテキストは変更されません。属性バインディングは双方向ではないためです。
[属性のエイリアスを考慮する]
プロパティエイリアスは、コンポーネントが完全に初期化された後でのみアクティブになります。初期化されていないエイリアスが参照されている場合、エラーが生成されます。さらに、属性エイリアスの属性エイリアスを生成すると、エラーも発生します。
既存の属性と同じ名前の属性エイリアスを作成できます。これにより、既存の属性が上書きされます。次に例を示します。次のQMLタイプには、color属性のエイリアスと、組み込みのRectangle属性のRectangle :: color属性があります。
[デフォルト属性]
オブジェクト定義には、デフォルト属性を含めることができます。オブジェクト()の子オブジェクトが、親オブジェクトに属性を割り当てずに別のオブジェクト(親オブジェクト)内で定義されている場合、子オブジェクトは親オブジェクトのデフォルトプロパティの値です。defaultキーワードは、デフォルト属性として宣言する必要があります。
たとえば、次のMyLabel.qmlファイルのオブジェクトには、someTextのデフォルトプロパティがあります。
MyLabelオブジェクト定義でsomeTextのデフォルトプロパティを割り当てることができます。
上記の2つは、次のものと同等です。
ただし、someTextプロパティはデフォルトプロパティとしてマークされているため、このデフォルトプロパティにTextオブジェクトを明示的に割り当てる必要はありません。
また、サブオブジェクトをサブ属性に明示的に追加しなくても、アイテムベースのタイプに追加できることに気づいたかもしれません。これは、Itemのデフォルト属性がdata属性であり、Itemに追加されたオブジェクトはすべて、子オブジェクトのリストに自動的に追加されるためです。
デフォルトの属性は、サブオブジェクトの再割り当てに非常に役立ちます。TabWidgetの例を見てください。この例では、デフォルトのプロパティを使用して、TabWidgetの子オブジェクトを子オブジェクトのリストとして自動的に再割り当てしています。
[読み取り専用属性]
オブジェクトの定義では、次の構文を使用して、readonlyキーワードを使用して読み取り専用属性を定義できます。
読み取り専用属性は、初期化中に値を指定する必要があります。読み取り専用属性が初期化されると、割り当て( "="を使用)か他の方法かに関わらず、それを割り当てることはできなくなります。
たとえば、次のComponent.onCompletedコードブロックは無効です。
注:読み取り専用属性は、デフォルト属性または属性別名として宣言できません。
【属性変更オブジェクト】
属性には、属性値変更オブジェクトを関連付けることができます。次のようにオブジェクトインスタンスを変更する属性を定義し、特定の属性に関連付けることができます。
上記の構文は、実際にはオブジェクト操作の既存のプロパティをインスタンス化するオブジェクト宣言であることに注意してください。
特定の属性変更タイプは特定の属性タイプにのみ適用できますが、これは言語によって強制されません。例:QtQuickモジュールが提供するNumberAnimationタイプは、数値タイプ(intやrealなど)のプロパティにのみ影響します。NumberAnimationが非数値プロパティに使用されている場合、エラーは発生しませんが、非数値プロパティはアニメーションを生成しません。属性変更タイプのアクションは、特定の属性の実現と密接に関連しています。
Signalプロパティ
信号は、特定のイベントが発生したときのオブジェクトタイプからの通知です。たとえば、プロパティの変更、アニメーションの開始または停止、または画像のダウンロードが完了したときです。たとえば、MouseAreaタイプは、ユーザーがクリックするとクリック信号を発信します。
シグナルが発生すると、オブジェクトはシグナルハンドラーを介して通知されます。シグナルハンドラーの定義構文は<Signal>にあり、<Signal>はシグナルの名前であり、最初の文字は大文字にする必要があります。シグナルハンドラーは、シグナルを発信するオブジェクトの定義内に実装する必要があり、シグナルハンドラーには、シグナルハンドラーが呼び出されたときに実行されるJavaScriptコードブロックを含める必要があります。
たとえば、MouseAreaオブジェクトの定義では、タイプonClickedのシグナルハンドラーを定義できます。MouseAreaがクリックされると、シグナルハンドラーが呼び出され、コンソールにメッセージが出力されます。
[信号属性の定義]
Q_SIGNALを使用して、C ++クラスでSignalプロパティを定義し、QML型システムに登録できます。オプションで、次の構文を使用してQMLドキュメントで信号属性を定義することもできます。
タイプブロックで同じ名前の2つの信号またはメソッドを定義すると、エラーが生成されます。ただし、既存の信号タイプを使用して新しい信号を定義できます(これにより、前の信号が非表示になります)。
以下は、信号定義の例です。
信号にパラメーターがない場合、「()」はオプションです。パラメーターを使用する場合は、上記のactionPerformedシグナルのstringおよびvalパラメーターなど、パラメーターのタイプを指定する必要があります。許可されるパラメーターの型は、前述のプロパティプロパティで定義されているものと同じです。
シグナルを発信するために、メソッドが呼び出されます。シグナルが発行されたときに、シグナルに関連付けられたシグナルハンドラーが実行され、ハンドラーは定義されたシグナルパラメーターの名前を使用して、予期されるパラメーターを取得できます。
【属性変更信号】
QMLタイプは、属性値が変更されたときに発生する組み込みの属性変更信号も提供します。次に、信号の利点とその使用方法を紹介します。
[シグナルハンドラ属性]
シグナルハンドラーは特別なメソッド属性タイプで、シグナルが発行されると、そのシグナルに関連付けられた特定のメソッドが呼び出されます。QMLにシグナルを追加すると、それに関連付けられたシグナルハンドラーが自動的に追加されます。デフォルトでは、関数は空です。クライアントは、プログラムロジックを実装するための独自の実装を提供できます。
SquareButton.qmlファイルで定義され、アクティブ化と非アクティブ化の2つの信号を定義する次のSquareButtonタイプについて考えてみます。
これらの信号は、同じディレクトリにある他のQMLファイル内の任意のSquareButtonオブジェクトから取得できます。クライアントは、信号ハンドラー実装も提供します。
[プロパティ変更シグナルハンドラ]
プロパティ変更のシグナルハンドラー構文は、<Property>で次のように変更されています。<Property>はプロパティの名前で、最初の文字は大文字にする必要があります。たとえば、TextInputタイプのドキュメントはtextChanged信号を定義していませんが、TextInputにはtext属性があるため、この信号は使用可能です。したがって、プロパティ値が変更されたときに呼び出されるonTextChangedシグナルハンドラーを実装することもできます。
メソッドのプロパティ
オブジェクトのメソッドは、処理を実行したり、イベントをトリガーしたりしたときに呼び出されます。メソッドがシグナルに接続されている場合、これらのメソッドはシグナルが送信されるときに実行されます。
[メソッド属性の定義]
Q_INVOKABLEを使用して、C ++クラスの関数またはC ++クラスのQ_SLOTを介してQML型システムに登録できます。オプションで、QMLドキュメントのオブジェクトにカスタムメソッドを追加することもできます。
メソッドをQMLタイプに追加して、再利用可能なJavaScriptコードを個別に定義できます。これらのメソッドは、内部または外部オブジェクトから呼び出すことができます。
シグナルとは異なり、パラメータータイプはデフォルトでvarタイプになっているため、ここでパラメータータイプを定義する必要はありません。
同じ型ブロックで同じ名前の2つのメソッドまたはシグナルを定義するビューは、エラーの原因になります。ただし、既存のメソッドの名前を使用して新しいメソッドを定義できます(これにより、既存のメソッドが使用できなくなります)。
次のRectangleタイプには、height値が指定されたときに呼び出されるcalculateHeight()メソッドがあります。
メソッドにパラメータがある場合、メソッド内のパラメータ名でそれらにアクセスできます。たとえば、MouseAreaをクリックすると、moveTo()メソッドが呼び出され、newXとnewYを使用してテキストの新しい位置を設定できます。
追加の属性と追加のSignalHandler
追加の属性と追加の信号処理メカニズムにより、オブジェクトは、オブジェクトによって参照されていない外部属性と信号ハンドラーを使用できます。これにより、オブジェクトは、単一のオブジェクトに関連付けられたプロパティと信号にアクセスできます。
QMLタイプの実装は、追加の特定の属性とシグナルを作成することを選択できます。このタイプのインスタンス化は実行時に作成され、これらのオブジェクトがプロパティと信号にアクセスできるようにします。
追加の属性とハンドラーを参照するための構文は次のとおりです。
たとえば、ListViewタイプには、ListViewのすべてのエージェントがアクセスできる追加のプロパティListView.isCurrentItemがあります。この属性は、現在選択されているアイテムを判別するために、各独立したプロキシオブジェクトによって使用できます。
この場合、追加のタイプの名前はListViewで、プロパティはCurrentItemです。追加のプロパティはListView.isCurrentItemを使用して参照されます。
この方法で、追加のシグナルハンドラーを参照することもできます。たとえば、追加のシグナルハンドラーはComponent.isCompletedで、コンポーネントの作成プロセスが完了したときにJavaScriptコードを実行するために使用できます。次の例では、ListModelが完全に作成されると、Component.onCompletedシグナルハンドラーが自動的に実行されます。
追加のタイプ名はComponentおよびcompletedシグナルです。追加のシグナルハンドラーは次のように参照できます:Component.isCompleted。
[追加属性とシグナルハンドラへのアクセスに関する注意]
よくある間違いは、追加のプロパティとシグナルハンドラーをサブオブジェクトから直接アクセスできるように設定することです。これは問題ありません。追加タイプのインスタンスは特定のオブジェクトにのみ追加され、オブジェクトとそのすべてのサブオブジェクトには追加されません。
例:次の例は、前の追加属性の例を改造したものです。この場合、エージェントはアイテムであり、長方形はアイテムの子オブジェクトです。
ListView.isCurrentItemはルートプロキシオブジェクトにのみアタッチされ、その子にはアタッチされないため、これは期待どおりに機能しません。Rectangleはエージェント自体ではなく、エージェントの子オブジェクトであるため、ListView.isCurrentItemを使用してisCurrentItemの追加プロパティにアクセスすることはできません。したがって、四角形はルートプロキシオブジェクトを介してisCurrentItemプロパティにアクセスする必要があります。
これで、delegateItem.ListView.isCurrentItemを通じてデリゲートのisCurrentItem添付プロパティを正しく参照することができます。