diff options
Diffstat (limited to 'src/qml/doc/src/qmllint/missing-type.qdoc')
-rw-r--r-- | src/qml/doc/src/qmllint/missing-type.qdoc | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/qml/doc/src/qmllint/missing-type.qdoc b/src/qml/doc/src/qmllint/missing-type.qdoc new file mode 100644 index 0000000000..466370ef39 --- /dev/null +++ b/src/qml/doc/src/qmllint/missing-type.qdoc @@ -0,0 +1,240 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qmllint-warnings-and-errors-missing-type.html +\ingroup qmllint-warnings-and-errors + +\title Missing Type +\brief A type used in a binding or alias was not found. + +This warning category has multiple warnings: +\list + \li \l{Cannot Deduce Type of Alias} + \li \l{No Type Found For Property} +\endlist + +\section1 Cannot Deduce Type of Alias + +\section2 What happened? +An alias property points to a property with a C++ type whose QML counterpart was not found. This can +be caused by importing a QML module which do not declare its QML dependencies on other modules. + +\note If you are importing QML modules with external dependencies, verify that they are +actually installed, and that their modules end up in an +\l{Import Statements#qml-import-path}{import path}. + +The warning might also indicate that the type of the property referenced by the alias does not have +a QML counterpart. The referenced property type might be missing the +\l{QQmlEngine::}{QML_ELEMENT} macro, for example. Refer to +\l{Defining QML Types from C++} or \l{Overview - QML and C++ Integration} in this case. + +\section2 Why is this bad? +QML tooling is not able to find the QML counterpart of the C++ type: the +\l{Qt Quick Compiler}{compiler} can't compile this property alias to +C++ and \l{qmllint Reference}{qmllint} as well as \l{\QMLLS Reference}{\QMLLS} +can't analyze this property alias. + +\section2 Example +Let our QML module have one C++ class with a property \c{myProperty}: + +\code +#include <QQuickItem> +#include <QtQml/qqmlregistration.h> +#include <QObject> + +class MyCppObject : public QObject +{ + Q_OBJECT + QML_ELEMENT +public: + MyCppObject(QObject *parent = nullptr) + : QObject(parent) + {} + + Q_PROPERTY(QQuickItem *myProperty READ myProperty WRITE setMyProperty NOTIFY notifyMyProperty) + QQuickItem *myProperty() { return m_myProperty; } + void setMyProperty(QQuickItem *item) { emit notifyMyProperty(); m_myProperty = item; } + +private: + QQuickItem *m_myProperty; + +signals: + void notifyMyProperty(); +}; +\endcode + +with following \c{CMakeLists.txt}: +\badcode +project(mymodule VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(appmymodule + main.cpp +) + +qt_add_qml_module(appmymodule + URI mymodule + VERSION 1.0 + QML_FILES Main.qml HelloWorld.qml + SOURCES mycppobject.cpp mycppobject.h +) + +target_link_libraries(appmymodule + PRIVATE Qt6::Quick +) +\endcode + +The C++ dependency \c{Quick} was declared, such that this class can compile and the QQuickItem +include can be found. Also, \c{mymodule} does not have any dependency on QtQuick. + +Now, let's try to use \c{myProperty} in an alias in QML. The program will run but QML tooling like +the \l{Qt Quick Compiler}{compiler}, for example, will complain about the usage of \c{myProperty}: +\qml +import mymodule + +MyCppObject { + id: root + + property alias myAlias: root.myProperty // not ok: Cannot deduce type of alias [missing-type] +} +\endqml +The reason for the warning message is that in the QML code, the type \c{QQuickItem} of +\c{myProperty} and its QML counterpart \c{Item} are not known, even if you have \c{import QtQuick} +in your QML file. This is because the same type can be exposed multiple times with different +attributes in different modules: \c{mymodule} actually has to be precise about the QML type of +\c{myProperty}. + +You can fix this warning by adding the dependency in the \c{CMakeLists.txt}: +\badcode +qt_add_qml_module(mymodule + URI mymodule + ... + # declarare QML dependency to QtQuick module + DEPENDENCIES QtQuick + ... +) +\endcode + +Now, the warning should be gone! + +\b {See also} \l {Declaring module dependencies}. + +\section1 No Type Found For Property + +\section2 What happened? +A binding was set on a property whose QML type was not found. This can be caused by a QML module +which does not declare its QML dependencies on other modules. + +\note If you are importing QML modules with external dependencies, verify that they are +actually installed, and that their modules end up in an +\l{Import Statements#qml-import-path}{import path}. + +The warning might also indicate that the type of the property does not have +a QML counterpart. The property type might be missing the +\l{QQmlEngine::}{QML_ELEMENT} macro, for example. Refer to +\l{Defining QML Types from C++} or \l{Overview - QML and C++ Integration} in this case. + +\section2 Why is this bad? +QML tooling is not able to find the QML counterpart of the C++ type: the +\l{Qt Quick Compiler}{compiler} can't compile this property binding to +C++ and \l{qmllint Reference}{qmllint} as well as \l{\QMLLS Reference}{\QMLLS} can't analyze this property binding. + +\section2 Example +Let our QML module have a C++ class with two properties, \c{myProperty} and \c{myProperty2}: + +\code +#include <QQuickItem> +#include <QtQml/qqmlregistration.h> +#include <QObject> + +class MyCppObject : public QObject +{ + Q_OBJECT + QML_ELEMENT +public: + MyCppObject(QObject *parent = nullptr) + : QObject(parent) + {} + + Q_PROPERTY(QQuickItem *myProperty READ myProperty WRITE setMyProperty NOTIFY notifyMyProperty) + QQuickItem *myProperty() { return m_myProperty; } + void setMyProperty(QQuickItem *item) { emit notifyMyProperty(); m_myProperty = item; } + + Q_PROPERTY(QQuickItem *myProperty2 READ myProperty2 WRITE setMyProperty2 NOTIFY notifyMyProperty2) + QQuickItem *myProperty2() { return m_myProperty2; } + void setMyProperty2(QQuickItem *item) { emit notifyMyProperty2(); m_myProperty2 = item; } + +private: + QQuickItem *m_myProperty; + QQuickItem *m_myProperty2; + +signals: + void notifyMyProperty(); + void notifyMyProperty2(); +}; +\endcode + +with following \c{CMakeLists.txt}: +\badcode +project(mymodule VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(appmymodule + main.cpp +) + +qt_add_qml_module(appmymodule + URI mymodule + VERSION 1.0 + QML_FILES Main.qml HelloWorld.qml + SOURCES mycppobject.cpp mycppobject.h +) + +target_link_libraries(appmymodule + PRIVATE Qt6::Quick +) +\endcode + +The C++ dependency \c{Quick} was declared, such that this class can compile and the QQuickItem +include can be found. Also, \c{mymodule} does not have any dependency on QtQuick. + +Now, let's try to bind \c{myProperty2} to \c{myProperty} in an alias in QML. The program will run +but QML tooling like the \l{Qt Quick Compiler}{compiler}, for example, will complain about the +usage of \c{myProperty}: + +\qml +import mymodule + +MyCppObject { + id: root + + myProperty: myProperty2 // not ok: No type found for property "myProperty". [missing-type] +} +\endqml +The reason for the warning message is that in the QML code, the type \c{QQuickItem} of \c{myProperty} +and its QML counterpart \c{Item} are not known: the dependency 'QtQuick' of mymodule was not +declared in the \c{CMakeLists.txt}. + +You can fix this warning by adding the dependency in the \c{CMakeLists.txt}: +\badcode +qt_add_qml_module(mymodule + URI mymodule + ... + # declarare QML dependency to QtQuick module + DEPENDENCIES QtQuick + ... +) +\endcode + +Now, the warning should be gone! + +\b {See also} \l {Declaring module dependencies}. +*/ + |