Qml signal to cpp



  • Hello,

    there are a lot of question with similar content.

    I use the qt stack qml and i want to send a signal from a qml to the cpp.
    In this documentation they use "view" but since i have a engine this wont work
    http://doc.qt.io/archives/qt-4.8/qtbinding.html#defining-new-qml-elements

    rootitem->dumpObjectInfo();
    in my cpp i can see the application window but to find the "child" of the main is not realy easy and a think it is also the wrong way to do this like i tryed.

    i mean the compiler says that the qmlsignal function is not supported
    onClicked: switch1.qmlSignal("on")

    Switch {
    id: switch1
    x: 41
    y: 293
    width: 200
    height: 40
    text: qsTr("Pumpe")
    font.pointSize: 16

        signal qmlSignal(string msg)
        
        onClicked: switch1.qmlSignal("on")
    }
    

    so i hope you can help me!
    Thanks.



  • maybe on step depper. in case i take the object:

    QList<QObject*> item = engine.rootObjects();
    qDebug() << item;
    

    then i just see the

    (QQuickApplicationWindow(0x2071ef5f300))



  • i think i achieved the first step.

    int main(int argc, char *argv[])
    {
    ...

    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    
    communicationbmlogic comob;
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("comob", &comob);
    

    but now i have a different problem.
    the switch is located in a different page (ManaulForm.ui.qml)
    But since this is a ui i should not write "user code" into it.
    So how can i create a connection between die ManualForm.ui.qml and the main.qml ore a ManualForm.qml?!?

    I need the Signal from the button in a qml which can communicate with the cpp



  • @gpio this is working code (Qt 5.9.0), mostly adapted from this documentation. Note I'm using Switch.checked to better reflect the status of the widget, selected (true) or not (false) to the C++ side.

    main.qml

    import QtQuick 2.6
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.4
    
    Window {
        id: window
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        signal qmlSignal(string msg)
    
        Switch {
            id: switch1
            x: 41
            y: 293
            width: 200
            height: 40
    
            onClicked: window.qmlSignal(switch1.checked)
        }
    }
    

    myclass.h

    #ifndef MYCLASS_H
    #define MYCLASS_H
    #include <QObject>
    #include <QDebug>
    
    class MyClass : public QObject
    {
        Q_OBJECT
    
    public slots:
        void cppSlot(const QString &msg) {
            qDebug() << "Called the C++ slot with message: " << msg;
        }
    };
    #endif // MYCLASS_H
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QList>
    #include <QQuickWindow>
    #include "myclass.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        MyClass myClass;
        QQuickWindow* window = (QQuickWindow*) engine.rootObjects().first();
        QObject::connect(window, SIGNAL(qmlSignal(QString)), &myClass, SLOT(cppSlot(QString)));
    
        return app.exec();
    }
    


  • Don't do that.

    Expose your c++ object to qml (as a context property or with qmlRegisterXXX) and then call a slot or a Q_INVOKABLE method of this object from QML.

    onClicked: cppObject.cppSlot("on")

    Not reaching into your UI layer from c++ will allow to keep a clean codebase and easier refactoring.
    Some more in-depth reasoning about this : https://www.youtube.com/watch?v=vzs5VPTf4QQ&feature=youtu.be&t=23m20s



  • @GrecKo thank you for pointing this out. I see the problems of going from C++ to QML as stated in the video (i.e. you change button into slider), great talk by the way.
    So my take-away is: always go from QML to C++ (I think C++ code as a "library" used by QML code).



  • Hello,

    thanks for your reply.
    i found a simple way to do this.
    First take this code into the main

    #include <QQmlContext>

    ...
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    communicationbmlogic contextPropertyClass;
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("contextPropertyClass", &contextPropertyClass);
    

    ...

    now just go to the ui file and make a connection with "add binding connection" in the left toolbar.
    In my case i took the "onToggeled" option end in the "Action" i put this code
    contextPropertyClass.on_buttonPumpOnOff_clicked(switch1.checked)

    now there are seperate connections.

    Connections {
        target: switch1
        onToggled: contextPropertyClass.on_buttonPumpOnOff_clicked(switch1.checked)
    }
    

    now every time i hit the button the class get "true" ore "false"
    perfect!



  • @gpio please if your issue is solved don't forget to mark your post as such. Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.