1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5\page qmllint-warnings-and-errors-signal-handler-parameters.html
6\ingroup qmllint-warnings-and-errors
8\title Signal Handler Parameters
9\brief The signal handler does not satisfy the signal types.
11This warning category has multiple warnings:
13 \li \l{Type Of Parameter In Signal Was Not Found}
14 \li \l{Type Of Parameter In Signal Cannot Be Used}
15 \li \l{The Signal Has A Parameter Of The Same Name}
19\section1 Type Of Parameter In Signal Was Not Found
21\section2 What happened?
22A signal handler tried to handle a signal with parameters of unknown QML types.
24Usually, this happens when handling C++ defined signals in QML when the module with the C++ defined
25signal does not properly declare its QML dependency to another QML module. If the module with the
26C++ defined signal compiles, then this is a sign that a dependency was only declared on the C++
27level and not on \l{qt_add_qml_module#declaring-module-dependencies}{the QML module level}.
29\note If you are importing QML modules with external dependencies, verify that they are
30actually installed, and that their modules end up in an
31\l{Import Statements#qml-import-path}{import path}.
33The warning might also indicate that the parameter type of the C++ defined signal does not have
34a QML counterpart. The parameter type might be missing the
35\l{QQmlEngine Class#QML_ELEMENT}{QML_ELEMENT} macro, for example. Refer to
36\l{Defining QML Types from C++} or \l{Overview - QML and C++ Integration} in this case.
38\section2 Why is this bad?
39In the first case, the module with the C++ signal has an undeclared dependency on the QML module
40level, which makes it hard to use the module, as users of the module need to guess the module's
43In both cases, QML tooling is not able to find the QML counterpart of the
44C++ type: the \l{Qt Quick Compiler}{compiler} can't compile this signal handler to
45C++ and \l{qmllint Reference}{qmllint} as well as \l{\QMLLS Reference}{\QMLLS}
46can't analyze this handler.
50Let our module have a C++ class with one \c{helloWorld} signal:
53#include <QtQml/qqmlregistration.h>
56class MyCppObject : public QObject
61 MyCppObject(QObject *parent = nullptr)
66 void helloWorld(QQuickItem *i);
70with following CMakeLists.txt:
72find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2)
74qt_standard_project_setup(REQUIRES 6.5)
76qt_add_executable(mymodule
80qt_add_qml_module(mymodule
84 SOURCES mycppobject.cpp mycppobject.h
87# declare C++ dependency to Quick
88target_link_libraries(appuntitled27
92The C++ dependency \c{Quick} was declared, such that this class can compile and the QQuickItem
93include can be found. Also, mymodule does not have any dependency on QtQuick.
95Now, lets try to handle this \c{helloWorld} signal in QML:
97import MyModule // name of the module with MyCppObject
100 onHelloWorld: function (x) { console.log(x); } // not ok: Type QQuickItem was not found!
104The reason of the warning message is that in the QML code, \c{QQuickItem} and its QML counterpart
105\c{Item} are not known: the dependency 'QtQuick' of MyModule was not declared in the CMakeLists.txt!
107You can add it as following in the qt_add_qml_module() call:
109qt_add_qml_module(mymodule
112 # declare QML dependencies to QtQuick:
118Now, the QML code should be fine again!
120\sa {qt_add_qml_module#declaring-module-dependencies}
123TODO: QML Lint cannot detect if you pass signal parameters by value, reference or pointer!
124Therefore, it will never print that warning.
125\section1 Type Of Parameter In Signal Should Be Passed By Pointer
126\section2 What happened?
129\section2 Why is this bad?
135You can fix this warning by TODO
139TODO: QML Lint cannot detect if you pass signal parameters by value, reference or pointer!
140Therefore, it will never print that warning.
142\section1 Type Of Parameter In Signal Should Be Passed By Value Or Const Reference
143\section2 What happened?
146\section2 Why is this bad?
152You can fix this warning by TODO
158\section1 Signal Handler Has More Formal Parameters Than The Signal It Handles
159\section2 What happened?
160A signal handler expects more parameters than what the signal will actually provide.
162\section2 Why is this bad?
163The extra parameters will be undefined.
170 signal helloWorld(x: QtObject) // signal expects only one parameter
172 onHelloWorld: function (x,y,z) {} // not ok: signal handler handles three parameters
175You can fix this warning by removing the extra parameters of the signal handler:
180 signal helloWorld(x: QtObject) // signal expects only one parameter
182 onHelloWorld: function (x) {} // ok: signal handler handles one parameter
186It can also be fixed by adding the missing parameters to the signal's declaration:
191 signal helloWorld(x: QtObject, y: int, y: int) // signal expects three parameters
193 onHelloWorld: function (x,y,z) {} // ok: signal handler handles three parameters
197\section1 The Signal Has A Parameter Of The Same Name
198\section2 What happened?
199The signal or signal handler might have swapped some of its arguments, or some arguments might be
202\section2 Why is this bad?
203This is very probably a typo and not intended by the user.
206\section3 Missing Arguments
211 signal helloWorld(x: QtObject, y: int)
213 onHelloWorld: function (y) {} // not ok: it seems that x was forgotten
217You can fix this warning by adding the missing parameters:
222 signal helloWorld(x: QtObject, y: int)
224 onHelloWorld: function (x, y) {} // ok: parameters have the same order as in helloWorld
227or by renaming the first parameter:
232 signal helloWorld(x: QtObject, y: int)
234 onHelloWorld: function (x) {} // ok: parameters have the same order as in helloWorld, even if y is missing
238\section3 Swapped Arguments
243 signal helloWorld(x: QtObject, y: int)
245 onHelloWorld: function (y, x) {} // not ok: helloWorld expects first 'x' then 'y'
249You can fix this warning by reordering the parameters in the correct order
254 signal helloWorld(x: QtObject, y: int)
256 onHelloWorld: function (x, y) {} // ok: parameters have the same order as in helloWorld