QML言語はJSONに似た構文を使用し、さまざまな式やメソッドをJavaScript関数として定義できます。また、JavaScriptファイルをインポートして、これらのインポートによって提供される機能を使用することもできます。
これにより、開発者とデザイナーはJavaScriptの知識を使用して、ユーザーインターフェイスとアプリケーションロジックをすばやく開発できます。
JavaScript式
QMLはJavaScriptと深く統合されており、JavaScriptでシグナルハンドラーとメソッドを定義できます。QMLのもう1つのコア機能は、プロパティバインディングを使用してオブジェクトプロパティ間の関係を指定および強化する機能です。これもJavaScriptを使用して定義されます。
QMLでのJavaScript式の使用の詳細については、QMLドキュメントでのJavaScript式というタイトルのドキュメントページを参照してください。
プロパティバインディングのJavaScript
次の例では、色属性長方形は、押されたプロパティTapHandlerに依存しています。この関係を説明するには、条件式を使用します。
QtQuick 2.12のインポート 長方形{ id:colorbutton 幅:200; 高さ:80; color:inputHandler.pressed?"steelblue": "lightsteelblue" TapHandler { id:inputHandler } }
実際、式の結果がその型をプロパティに割り当てることができる値である限り、(どんなに複雑であっても)プロパティバインディング定義で任意のJavaScript式を使用できます。これには副作用が含まれます。ただし、コードのパフォーマンス、可読性、保守性が低下するため、複雑なバインディングと副作用を使用することはお勧めしません。
プロパティバインディングを定義するには2つの方法があります。最も一般的な方法は、前の例でのプロパティの初期化です。2番目の方法(これもまれな方法です)は、以下に示すように、Qt.binding()関数から返された関数を命令型JavaScriptコードの属性に割り当てることです。
QtQuick 2.12のインポート 長方形{ id:colorbutton 幅:200; 高さ:80; 赤色" TapHandler { id:inputHandler } Component.onCompleted:{ color = Qt.binding(function(){return inputHandler.pressed? "steelblue": "lightsteelblue"}); } }
属性バインディングの定義方法の詳細については、属性バインディングのドキュメントを参照してください。バインディングと値の割り当ての違いについては、属性の割り当てと属性バインディングに関するドキュメントを参照してください。
シグナルハンドラーのJavaScript
QMLオブジェクトタイプは、特定のイベントの発生に応答して信号を発信できます。これらの信号は、カスタムプログラムロジックを実装するためにクライアントが定義できる信号処理プログラム関数で処理できます。
Rectangle型で表されるボタンにTapHandlerタグとTextタグがあるとします。TapHandlerは、ユーザーがボタンを押したときにタップ信号を送信します。クライアントは、JavaScriptの式onTappedを使用して、ハンドラーのシグナルに反応できます。QMLエンジンは、ハンドラーで定義されたこれらのJavaScript式を必要に応じて実行します。通常、シグナルハンドラーはJavaScript式にバインドされ、他のイベントを開始したり、プロパティ値を割り当てたりします。
QtQuick 2.12のインポート 長方形{ id:ボタン 幅:200; 高さ:80; 色:「lightsteelblue」 TapHandler { id:inputHandler onTapped:{ //任意のJavaScript式 console.log( "タップされました!") } } テキスト{ id:ラベル anchors.centerIn:親 テキスト:inputHandler.pressed?「押された!」: "ここを押してください!" } }
シグナルとシグナルハンドラーの詳細については、以下のトピックを参照してください。
シグナルおよびハンドラーイベントシステム
QMLオブジェクトのプロパティ
スタンドアロン関数のJavaScript
プログラムロジックは、JavaScript関数で定義することもできます。これらの関数は、QMLドキュメントで(カスタムメソッドとして)インラインで定義することも、インポートしたJavaScriptファイルで外部で定義することもできます。
カスタムメソッドのJavaScript
カスタムメソッドはQMLドキュメントで定義でき、シグナルハンドラー、属性バインディング、または他のQMLオブジェクトの関数から呼び出すことができます。このようなメソッドは、その実装が外部JavaScriptファイルではなくQMLオブジェクトタイプ定義(QMLドキュメント)に含まれているため、インラインJavaScript関数と呼ばれることがよくあります。
インラインカスタムメソッドの例は次のとおりです。
QtQuick 2.12のインポート アイテム{ 関数fibonacci(n){ var arr = [0、1]; for(var i = 2; i <n + 1; i ++) arr.push(arr [i-2] + arr [i -1]); arrを返します。 } TapHandler { onTapped:console.log(fibonacci(10)) } } TapHandlerがタップされた信号を送信するときはいつでも、それはフィボナッチ関数を実行します。
注:QMLドキュメントでインラインで定義されたカスタムメソッドは他のオブジェクトに公開されるため、QMLコンポーネントのルートオブジェクトのインライン関数は、コンポーネントの外部の呼び出し元プログラムから呼び出すことができます。これを実行したくない場合は、メソッドを非ルートオブジェクトに追加するか、外部のJavaScriptファイルに書き込むことをお勧めします。
JavaScriptを使用してQMLでカスタムメソッドを定義する方法の詳細については、QMLオブジェクトプロパティのドキュメントをご覧ください。
JavaScriptファイルで定義された関数
簡単なプログラムロジックを別のJavaScriptファイルに分離するのが最善です。QMLモジュールなどのインポート文を使用して、ファイルをQMLにインポートできます。
たとえば、fibonacci()は、前の例のメソッドをfib.jsという名前の外部ファイルに移動して、次のようにアクセスできます。
QtQuick 2.12のインポート MathFunctionsとして「fib.js」をインポートする アイテム{ TapHandler { onTapped:console.log(MathFunctions.fibonacci(10)) } } 外部JavaScriptファイルをQMLにロードする方法の詳細については、QMLでのJavaScriptリソースのインポートに関するセクションをご覧ください。
信号をJavaScript関数に接続する
前のセクションで説明したように、シグナルを送信するQMLオブジェクトタイプは、そのシグナルのデフォルトのシグナルハンドラーも提供します。ただし、別のQMLオブジェクトがシグナルを送信したときに、クライアントがQMLオブジェクトで定義された関数をトリガーしたい場合があります。このような状況は、信号接続を介して処理できます。
信号のconnect()メソッドを呼び出し、JavaScript関数をパラメーターとして渡すことにより、QMLオブジェクトによって発行された信号をJavaScript関数に接続できます。たとえば、次のコードは、TapHandlerのTapped信号をscript.jsのjsFunction()に接続します。
QtQuick 2.12のインポート Myscriptとして「script.js」をインポート アイテム{ id:item 幅:200; 高さ:200 TapHandler { id:inputHandler } Component.onCompleted:{ inputHandler.tapped.connect(MyScript.jsFunction) } }
// script.js function jsFunction(){ console.log( "呼び出されたJavaScript関数!") }
jsFunction()では、TapHandlerと呼ばれるタップされた信号が発行されます。
詳細については、メソッドとシグナルへのシグナルの接続を参照してください。
アプリケーション起動コードのJavaScript
アプリケーション(またはコンポーネントインスタンス)の起動時に、いくつかのコマンドコードを実行する必要がある場合があります。スタートアップスクリプトをグローバルコードとして外部スクリプトファイルに含めるのは簡単ですが、QML環境が完全に確立されていない可能性があるため、これは厳しく制限される可能性があります。たとえば、一部のオブジェクトが作成されていない場合や、一部の属性バインディングが確立されていない場合があります。グローバルスクリプトコードの厳密な制限については、JavaScript環境の制限を参照してください。
QMLオブジェクトのインスタンス化が完了すると、Component.completedの追加のシグナルが発行されます。オブジェクトをインスタンス化した後、Component.onCompletedは対応するハンドラーでJavaScriptコードを実行します。したがって、このオブジェクトはComponent.completedがQML環境を完全に確立したときに生成されるため、アプリケーションの起動コードを記述するのに最適な場所は、トップレベルのObject.onCompletedオブジェクトのハンドラーです。
たとえば、次のとおりです。
QtQuick 2.0のインポート 長方形{ function startupFunction(){ // ...起動コード } Component.onCompleted:startupFunction();
QMLファイル内のすべてのオブジェクト(ネストされたオブジェクトおよびネストされたQMLコンポーネントインスタンスを含む)は、この追加属性を使用できます。起動時に実行される複数のonCompleted()ハンドラーがある場合、それらは未定義の順序で順次実行されます。
同様に、各オブジェクトが破棄される前に、コンポーネントはdestroy()シグナルを発行します。
JavaScriptリソース
JavaScript関数で定義されたアプリケーションロジックは、JavaScriptリソースと呼ばれる個別のJavaScriptファイルに分割できます。JavaScriptリソースにはいくつかの異なるタイプがあり、セマンティクスが異なります。
QMLのJavaScriptリソースの定義の詳細については、QMLでのJavaScriptリソースの定義というタイトルのドキュメントページを参照してください。
JavaScriptインポート
QMLドキュメントはJavaScriptリソースをインポートでき、JavaScriptリソースは他のJavaScriptリソースとQMLモジュールをインポートできます。これにより、アプリケーション開発者はモジュール式の独立したファイルでアプリケーションロジックを提供できます。
JavaScriptリソースをインポートする方法とそれらが提供する関数を使用する方法の詳細については、「JavaScriptリソースのインポート」というタイトルのドキュメントページを参照してください。
JavaScriptホスト環境
QMLエンジンが提供するJavaScript環境は、Webブラウザーが提供するJavaScript環境とは異なります。環境で実行されるコードには特定の制限が適用され、QMLエンジンは、JavaScript開発者が慣れていないルートコンテキストでさまざまなオブジェクトを提供します。
これらの制限と拡張は、QMLエンジンによって提供されるJavaScriptホスト環境の説明に記載されています。