JavaScriptホスト環境

QMLでは、QMLアプリケーションを書くためのJavaScriptホスト環境を提供しています。この環境はブラウザやNode.jsのようなサーバサイドのJavaScript環境が提供するホスト環境とは異なります。例えば、QMLはブラウザ環境で一般的に見られるようなwindow オブジェクトやDOM API を提供しません。

共通ベース

ブラウザやサーバサイドJavaScript環境と同様に、QMLランタイムはECMAScript言語仕様標準を実装しています。これにより、Object、Array、Math などの標準によって定義されたすべての組み込み型や関数にアクセスすることができます。QMLランタイムはECMAScript言語仕様の第7版を実装しています。

Nullish Coalescing(??) (Qt 5.15 以降)とOptional Chaining(?.) (Qt 6.2 以降)も QML ランタイムに実装されています。

標準的な ECMAScript 組み込み関数については、QML のドキュメントには明示的に記述されていません。これらの使用方法については、ECMA-262 第 7 版を参照するか、W3Schools JavaScript Reference(JavaScript Objects Reference セクション) のような多くのオンライン JavaScript リファレンスやチュートリアルサイトを参照してください。多くのサイトはブラウザの JavaScript に焦点を当てているので、ある関数やオブジェクトが標準の ECMAScript の一部なのか、それともブラウザ環境に特化したものなのかを判断するために、仕様を再確認する必要があるかもしれません。上記のW3Schoolsのリンクの場合、JavaScript Objects Reference のセクションは一般的に標準をカバーしていますが、Browser Objects ReferenceHTML DOM Objects Reference のセクションはブラウザ固有のものです(したがってQMLには適用されません)。

型注釈とアサーション

QML文書中の関数宣言は型注釈を含むことができ、また含むべきです。型アノテーションは引数の宣言や関数自体に付加され、戻り値の型をアノテーションします。次の関数はintstring を引数にとり、QtObject を返します:

function doThings(a: int, b: string) : QtObject { ... }

型アノテーションは、Qt Creatorや qmllintのようなツールがコードを理解し、より良い診断を提供するのに役立ちます。さらに、C++からの関数の利用を容易にします。詳しくはC++ から QML オブジェクトを操作するを参照してください。

型アサーション(as-cast と呼ばれることもあります)は、オブジェクトを別のオブジェ クト型にキャストするためにも使うことができます。オブジェクトが実際に指定された型であれば、型アサーションは同じオブジェクトを返します。そうでない場合はnull を返します。以下のスニペットでは、parent オブジェクトの特定のメンバにアクセスする前に、Rectangle であることを表明しています。

Item {
    property color parentColor: (parent as Rectangle)?.color || "red"
}

オプションの連結 (?.) を使用すると、親が実際には矩形でない場合に例外がスローされるのを回避できます。その場合、"red" がparentColor として選択されます。

Qt 6.7以降、型アノテーションは関数を呼び出すときに常に強制されます。値は必要に応じて必要な型に強制されます。以前は、型アノテーションはインタプリタとJITコンパイラでは無視されましたが、C++にコンパイルするときにqmlcachegenと qmlscによって強制されました。このため、いくつかのコーナーケースで動作が異なることがありました。インタープリタやJITの旧来の動作を明示的に要求するためには、QMLドキュメントに以下を追加してください:

pragma FunctionSignatureBehavior: Ignored

QMLグローバルオブジェクト

QML JavaScriptのホスト環境では、QMLグローバルオブジェクトのドキュメントで詳しく説明されているように、多くのホストオブジェクトや関数が実装されています。

これらのホストオブジェクトや関数は、モジュールがインポートされているかどうかに関わらず、常に利用することができます。

JavaScript オブジェクトと関数

QML エンジンがサポートする JavaScript オブジェクト、関数、プロパティの一覧は、JavaScript オブジェクトと関数の一覧にあります。

なお、QML はネイティブオブジェクトに対して以下のような修正を加えています:

  • String プロトタイプにarg() 関数が追加されています。
  • DateNumber のプロトタイプにロケールを意識した変換関数が追加されています。

さらに、QMLではinstanceof関数の動作を拡張し、QMLの型に対する型チェックを 可能にしています。これは、例えば、ある変数が本当に期待した型であるかどうかを確認するために使用することができることを意味します:

var v = something();
if (!v instanceof Item) {
    throw new TypeError("I need an Item type!");
}

...

JavaScript環境の制限

QMLではJavaScriptのコードに対して以下のような制限を設けています:

  • .qml ファイルに書かれた JavaScript コードはグローバルオブジェクトを変更することはできません。.jsファイルに書かれたJavaScriptコードはグローバルオブジェクトを変更することができ、その変更は.qmlファイルをインポートしたときに見えるようになります。

    QMLでは、グローバルオブジェクトは不変であり、既存のプロパティを変更・削除したり、新しいプロパティを作成したりすることはできません。

    ほとんどのJavaScriptプログラムは意図的にグローバルオブジェクトを変更することはありません。しかし、JavaScriptが宣言されていない変数を自動的に生成することは、暗黙のうちにグローバルオブジェクトを変更することになり、QMLでは禁止されています。

    a という変数がスコープチェーンに存在しないと仮定すると、以下のコードは QML では不正です:

    // Illegal modification of undeclared variable
    a = 1;
    for (var ii = 1; ii < 10; ++ii)
        a = a * ii;
    console.log("Result: " + a);

    これを合法なコードに修正することは簡単です。

    var a = 1;
    for (var ii = 1; ii < 10; ++ii)
        a = a * ii;
    console.log("Result: " + a);

    暗黙的にも明示的にも、グローバル・オブジェクトを変更しようとすると例外が発生する。捕捉されない場合、警告が表示され、その警告には問題のあるコードのファイルと行番号が含まれます。

  • グローバルコードは縮小されたスコープで実行されます。

    起動時、QMLファイルに「グローバル」なコードを含む外部JavaScriptファイルが含まれている場合、そのコードは外部ファイル自身とグローバルオブジェクトのみを含むスコープで実行されます。つまり、通常はアクセスできるはずのQMLオブジェクトやプロパティにはアクセスできません。

    スクリプトのローカル変数にのみアクセスするグローバルコードは許可されます。これは有効なグローバルコードの例です。

    var colors = [ "red", "blue", "green", "orange", "purple" ];

    QMLオブジェクトにアクセスするグローバルコードは正しく実行されません。

    // Invalid global code - the "rootObject" variable is undefined
    var initialPosition = { rootObject.x, rootObject.y }

    この制限は、QML環境がまだ完全に確立されていないために存在します。環境構築が完了した後にコードを実行するには、アプリケーション起動コードの JavaScript を参照してください。

  • this の値はQMLではほとんどの場合未定義です。

    this キーワードはJavaScriptからプロパティをバインディングする際に使用できます。QML バインディング式、QML シグナルハンドラ、および QML 宣言関数では、this はスコープオブジェクトを指します。それ以外の状況では、this の値はQMLでは未定義です。

    特定のオブジェクトを参照するにはid を指定します:

    Item {
        width: 200; height: 100
        function mouseAreaClicked(area) {
            console.log("Clicked in area at: " + area.x + ", " + area.y);
        }
        // This will pass area to the function
        MouseArea {
            id: area
            y: 50; height: 50; width: 200
            onClicked: mouseAreaClicked(area)
        }
    }

スコープと命名解決も参照してください

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