QMLにおけるJavaScriptリソースの定義

QMLアプリケーションのプログラムロジックはJavaScriptで定義することができます。JavaScriptのコードは、QML文書の中でインラインで定義することもできますし、JavaScriptファイル(QMLではJavaScript Resources )に分割して定義することもできます。

QMLでサポートされているJavaScriptのリソースには、コードビハインド実装ファイルと 共有(ライブラリ)ファイルの2種類があります。どちらの種類のJavaScriptリソースも、他のJavaScriptリソースからインポートしたり、QMLモジュールに含めることができます。

コードビハインド実装ファイル

QML文書にインポートされるJavaScriptファイルの多くは、インポートするQML文書のためのステートフル実装です。このような場合、文書内で定義されている QML オブジェクトの各インスタンスは、正しく動作するために、JavaScript のオブジェクトと状態を別々にコピーする必要があります。

JavaScript ファイルをインポートする際のデフォルトの動作は、各 QML コンポーネントのインスタンスに対して一意の独立したコピーを提供することです。もしその JavaScript ファイルが.import 文でリソースやモジュールをインポートしていなければ、そのコードは QML コンポーネントのインスタンスと同じスコープで実行され、その結果、その QML コンポーネントで宣言されたオブジェクトやプロパティにアクセスし、操作することができます。そうでない場合は、独自のスコープを持つことになり、QML コンポーネントのオブジェクトやプロパティが必要な場合は、JavaScript ファイルの関数にパラメータとして渡す必要があります。

以下にコード・ビハインド実装リソースの例を示します:

// MyButton.qml
import QtQuick 2.0
import "my_button_impl.js" as Logic // A new instance of this JavaScript resource
                                    // is loaded for each instance of Button.qml.

Rectangle {
    id: rect
    width: 200
    height: 100
    color: "red"

    MouseArea {
        id: mousearea
        anchors.fill: parent
        onClicked: Logic.onClicked(rect)
    }
}
// my_button_impl.js
var clickCount = 0;   // this state is separate for each instance of MyButton
function onClicked(button) {
    clickCount += 1;
    if ((clickCount % 5) == 0) {
        button.color = Qt.rgba(1,0,0,1);
    } else {
        button.color = Qt.rgba(0,1,0,1);
    }
}

一般的に、単純なロジックはQMLファイルのインラインで定義すべきですが、より複雑なロジックは、保守性や可読性の観点から、code-behind実装リソースに分離すべきです。

共有JavaScriptリソース(ライブラリ)

デフォルトでは、QMLからインポートされたJavaScriptファイルはQMLコンポーネントと コンテキストを共有します。つまり、JavaScriptファイルは同じQMLオブジェクトにアクセスし、それらを変更することができます。その結果、インポートされたファイルはそれぞれ一意でなければなりません。

前節では、JavaScript ファイルのステートフルインポートについて説明しました。しかし、一部のJavaScriptファイルはステートレスで、再利用可能なライブラリのように動作します。つまり、インポート元からは何も必要としないヘルパー関数のセットを提供します。このようなライブラリは、以下の例のように特別なプラグマでマークすることで、 メモリを大幅に節約し、QMLコンポーネントのインスタンス化を高速化することができます。

// factorial.js
.pragma library

var factorialCount = 0;

function factorial(a) {
    a = parseInt(a);

    // factorial recursion
    if (a > 0)
        return a * factorial(a - 1);

    // shared state
    factorialCount += 1;

    // recursion base-case.
    return 1;
}

function factorialCallCount() {
    return factorialCount;
}

このプラグマ宣言は、コメントを除く JavaScript コードの前に記述する必要があります。

複数のQMLドキュメントが"factorial.js" をインポートし、それが提供する factorial関数やfactialCallCount関数を呼び出すことができることに注意してください。JavaScriptインポートの状態は、インポートしたQMLドキュメント間で共有されるため、 factorial関数を呼び出さないQMLドキュメント内で factorialCallCount関数を呼び出すと、戻り値が0でない場合があります。

例えば

// Calculator.qml
import QtQuick 2.0
import "factorial.js" as FactorialCalculator // This JavaScript resource is only
                                             // ever loaded once by the engine,
                                             // even if multiple instances of
                                             // Calculator.qml are created.

Text {
    width: 500
    height: 100
    property int input: 17
    text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input)
}

.pragmaライブラリファイルは共有されているため、QMLコンポーネントのインスタンスオブジェクトやプロパティに直接アクセスすることはできませんが、関数のパラメータとしてQMLの値を渡すことはできます。

©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。