シグナルハンドラのパラメータ

この警告カテゴリーはqmllintによって[signal-handler-parameters]

この警告カテゴリには複数の警告があり、以下のセクションで説明します:

シグナルのパラメータの型が見つかりません

何が起こりましたか?

シグナルハンドラが未知の QML 型のパラメータを持つシグナルを扱おうとしました。

通常、C++で定義されたシグナルをQMLで扱う場合、C++で定義されたシグナルを持つモジュールが他のQMLモジュールとの依存関係を適切に宣言していない場合に発生します。もしC++で定義されたシグナルを持つモジュールがコンパイルされるのであれば、これは依存関係がC++のレベルで宣言されただけで、QMLモジュールのレベルでは宣言されていないことを示しています。

注意: 外部依存関係のあるQMLモジュールをインポートする場合、そのモジュールが 実際にインストールされているか、インポートパスにそのモジュールが含まれているか を確認してください。

この警告は、C++で定義されたシグナルのパラメータ型にQMLの対応するものがない ことを示している可能性があります。例えば、QML_ELEMENT マクロがない可能性があります。このような場合は「C++からQMLの型を定義する」または「概要 - QMLとC++の統合」を参照してください。

これはなぜ悪いのでしょうか?

最初のケースでは、C++のシグナルを持つモジュールがQMLモジュールレベルで宣言されていない依存関係を持つため、モジュールの利用者はモジュールの隠れた依存関係を推測する必要があり、モジュールの利用が困難になります。

どちらの場合も、QMLツールはC++型に対応するQML型を見つけることができません。コンパイラはこのシグナルハンドラをC++にコンパイルすることができず、qmllintや QML Language Serverはこのハンドラを解析することができません。

helloWorld シグナルを一つ持つ C++ クラスがあるとします:

#include <QQuickItem>
#include <QtQml/qqmlregistration.h>
#include <QObject>

class MyCppObject : public QObject
{
 Q_OBJECT
 QML_ELEMENT
public:
 MyCppObject(QObject *parent = nullptr)
     : QObject(parent)
 {}

signals:
 void helloWorld(QQuickItem *i);

};

というシグナルを持つ C++ クラスがあるとします:

find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2)

qt_standard_project_setup(REQUIRES 6.5)

qt_add_executable(mymodule
 main.cpp
)

qt_add_qml_module(mymodule
    URI MyModule
    VERSION 1.0
    QML_FILES Main.qml
    SOURCES mycppobject.cpp mycppobject.h
)

# declare C++ dependency to Quick
target_link_libraries(appuntitled27
 PRIVATE Qt6::Quick
)

C++ 依存関係Quick が宣言されているので、このクラスはコンパイルでき、QQuickItem インクルードが見つかります。また、mymodule にはQtQuick への依存はありません。

では、このhelloWorld シグナルを QML で処理してみましょう:

import MyModule // name of the module with MyCppObject

MyCppObject {
    onHelloWorld: function (x) { console.log(x); } // not ok: Type QQuickItem was not found!
}

警告メッセージが表示される理由は、QMLのコードの中で、QQuickItem とそのQMLの対応物であるItem が知られていないからです:MyModuleの依存関係 'QtQuick' がCMakeLists.txtで宣言されていません!

qt_add_qml_module()呼び出しで追加できます:

qt_add_qml_module(mymodule
    URI MyModule
    ...
    # declare QML dependencies to QtQuick:
    DEPENDENCIES QtQuick
    ...
)

これで、QMLのコードは正常になります!

シグナルハンドラが、扱うシグナルよりも正式なパラメータを持っている

何が起こったのでしょうか?

シグナルハンドラは、シグナルが実際に提供するものよりも多くのパラメータを期待します。

これはなぜ悪いのでしょうか?

余分なパラメータは未定義になるからです。

import QtQuick

Item {
    signal helloWorld(x: QtObject)  // signal expects only one parameter

    onHelloWorld: function (x,y,z) {} // not ok: signal handler handles three parameters
}

この警告を修正するには、シグナルハンドラの余分なパラメータを削除するか、足りないパラメータをシグナルの宣言に追加します:

import QtQuick

Item {
    signal helloWorld(x: QtObject)  // signal expects only one parameter

    onHelloWorld: function (x) {} // ok: signal handler handles one parameter

    signal alternativeHelloWorld(x: QtObject, y: int, y: int)  // signal expects three parameters

    onAlternativeHelloWorld: function (x,y,z) {} // ok: signal handler handles three parameters
}

シグナルには同じ名前のパラメータがあります

何が起こったのか?

シグナルまたはシグナルハンドラが引数の一部を入れ替えたか、引数の一部が欠落している可能性があります。

なぜ悪いのか?

これはおそらくタイプミスで、ユーザーが意図したものではありません。

引数の欠落

import QtQuick

Item {
    signal helloWorld(x: QtObject, y: int)

    onHelloWorld: function (y) {} // not ok: it seems that x was forgotten
}

この警告を修正するには、足りない引数を追加するか、最初の引数の名前を変更してください:

import QtQuick

Item {
    signal helloWorld(x: QtObject, y: int)

    onHelloWorld: function (x, y) {} // ok: parameters have the same order as in helloWorld

    signal alternativeHelloWorld(x: QtObject, y: int)

    onAlternativeHelloWorld: function (x) {} // ok: parameters have the same order as in helloWorld, even if y is missing
}

引数の入れ替え

import QtQuick

Item {
    signal helloWorld(x: QtObject, y: int)

    onHelloWorld: function (y, x) {} // not ok: helloWorld expects first 'x' then 'y'
}

この警告を修正するには、パラメータの順番を正しくしてください:

import QtQuick

Item {
    signal helloWorld(x: QtObject, y: int)

    onHelloWorld: function (x, y) {} // ok: parameters have the same order as in helloWorld
}

qt_add_qml_module#declaring-module-dependenciesも参照してください

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