Search code examples
qtqmlqtquick2qt6qtquick-designer

Qt 6.5 how to use c++ functions when using ui.qml and qml files


Using Qt 6.5 I have created a brand new Qt Quick Application from the Create Project button in the Welcome menu.

This new project creates some base files by default when I keep the "Create a project that you can open in Qt Design Studio" button checked:

enter image description here

Approaching this as a first time user of Quick, this directory structure is very confusing for me. Especially since the Qt6 docs have this seemingly simple example of how to call C++ functions from QML: enter link description here

The docs link says that I should also be creating a qt_add_qml_module into some CMake file so that I can import <MyModule>. In the project template that is generated for me, which CMake file do I add this too, and what exactly am I supposed to add?

Further, because this template that is generated upon project creation includes a ui.qml and you can't call functions from ui.qml files, what exactly should I be doing here?

I've tried to compare and contrast the example hangman quick project, which does include calling C++ functions. Since this example project does not include any ui.qml files, though, it is difficult to translate the concepts to this default project of mine.

Can someone explain how to do this? I truly need the "Explain it to me like I'm 5".


Solution

  • Although I did not implement it in the test project I posted above, I ultimately did the following to access c++ classes in QML:

    1. Create a new .h/.cpp file. Add QObject as the base class, include QObject, Add Q_OBJECT, and Add QML_ELEMENT

    reference picture

    1. In the .h file, add Q_INVOKABLE before the function you'd like to call in QML. Add #include <QtQml> as it is needed to access Q_INVOKABLE. For example:
    // PartyTime.h
    #ifndef PARTYTIME_H
    #define PARTYTIME_H
    
    #include <QObject>
    #include <QtQml>
    
    class PartyTime : public QObject
    {
        Q_OBJECT
        QML_ELEMENT
    public:
        explicit PartyTime(QObject *parent = nullptr);
    
        Q_INVOKABLE void party();
    
    signals:
    
    };
    
    #endif // PARTYTIME_H
    
    1. In my CMakeLists.txt, find the qt_add_qml_module function that is generated for you. Copy the URI value.

    2. At the top of my Main.qml file, import <qml-module-URI>

    3. Now you can add a QML object of your class. For example:

    // Main.qml
    import QtQuick
    import QtQuick.Window
    import QtQuick.Controls
    import <qml-module-URI>
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        PartyTime {
            id: partyTime
        }
    
        Button {
            id: partyTimeBtn
            text: "Click to start party"
            onClicked: partyTime.party()
        }
    }