[SOLVED]Signal and Slot between qml and c++



  • Hello,

    I want to execute a method in c++ by clicking a button in a qml interface by sending a signal in the qml file and receiving it in the c++ file.

    But when I cklick the button the program doesn't execute the method. I don't know where the error is. Maybe someone of you will find the error or could give me a hint?

    Thank you for all answers!

    Here is my code so far:

    main.qml
    @
    import QtQuick 2.0

    Rectangle {
    id: main
    width: 500
    height: 300

    //create signal
    signal trigger_signal (string msg)
    
    //only for testing the signal. When I click the button the text "signal sent successful..." is in the console. So the signal must be sent successful
    
    onTrigger_signal: console.log("signal sent successful with number " + msg)
    
    
    
    Rectangle {
        id: trigger1
        x: 27
        y: 22
        width: 80
        height: 80
        color: "#ffffff"
        border.width: 5
        border.color: "#000000"
    
        Text {
            id: trigger1_text
            x: 19
            y: 33
            text: qsTr("Trigger1")
            font.pixelSize: 12
        }
    
        MouseArea {
            id: trigger1_mousearea
            anchors.fill: parent
            hoverEnabled: true
            onEntered: parent.border.color = "green"
            onExited: parent.border.color = "black"
            onClicked: {
                console.log("Trigger1 clicked")
    
                //send signal...
                main.trigger_signal ("1")
            }
        }
    }
    

    }
    @

    main.cpp
    @
    #include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include <QQuickItem>
    #include <QObject>
    #include <QString>
    #include <QStringList>
    #include <QFile>
    #include <QProcess>
    #include <iostream>
    #include <QDebug>
    #include <string>

    using namespace std;

    class Dialog : public QObject
    {
    Q_OBJECT

    public slots:
    //create slot...
    void trigger_slot(const QString &msg)
    {
    cout << "Trigger received" << endl;
    qDebug() << "Trigger received with number " << msg;
    }

    };

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile&#40;QStringLiteral("qml/Qml_Simpack_Trigger/main.qml"&#41;&#41;;
    viewer.showExpanded(&#41;;
    
    
    //connect signal and slot
    QQuickView
    view(QUrl::fromLocalFile&#40;"qml/Qml_Simpack_Trigger/main.qml"&#41;&#41;;
    QQuickItem *item = view.rootObject(&#41;;
    
    Dialog dialog;
    QObject::connect(item, SIGNAL(trigger_signal(QString)), &dialog, SLOT(trigger_slot(QString)));
    
    
    return app.exec(&#41;;
    

    }

    @



  • Hi la-ga.

    Try to call signal without main, like
    @trigger_signal("1")@

    Do you get any errors?


  • Moderators

    Hi,

    Do you get the messages "Trigger1 clicked" or "signal sent successful with number "?

    Does the button border change colour when you enter/exit?



  • [quote author="JKSH" date="1385820195"]Hi,

    Do you get the messages "Trigger1 clicked" or "signal sent successful with number "?

    Does the button border change colour when you enter/exit?[/quote]

    Hi JKSH,

    thank you for your answer.

    When I enter/exit the rectangle the border color changes correctly.

    When I click in the rectangle I get the message:
    "Trigger 1 clicked"
    "signal sent successful with number 1"

    But I don't get the messages out of the c++ method.


  • Moderators

    I just noticed that you declared your Dialog in main.cpp.

    QObjects need to be declared in a .h file. The "Meta-Object Compiler":http://qt-project.org/doc/qt-5.1/qtdoc/moc.html doesn't process .cpp files. From the documentation:

    The moc tool reads a C++ header file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces a C++ source file containing the meta-object code for those classes.... Meta-object code is required for the signals and slots mechanism...



  • Another problem I noticed is that you are instantiating two QML viewers: QtQuick2ApplicationViewer and then a QQuickView. I believe this will create two separate instances of the QML object trees. The signal/slot connection in main.cpp is being made with the Qt Quick view that isn't being shown. You'll want instantiate and display the QML scene using either QtQuick2ApplicationViewer or QQuickView (but not both).



  • Hey,

    thank you JKSH and fonzl for your answer. Now the program does what i want from it.

    Here is my program code. Maybe it will help someone with the same problem:

    main.qml
    @
    import QtQuick 2.0

    Rectangle {
    id: main
    width: 360
    height: 360

    //create signal...
    
    signal trigger_signal(string msg)
    
    //when signal is sent...
    
    onTrigger_signal: console.log("signal sent successful with number " + msg)
    
    Rectangle {
        id: button1
        x: 116
        y: 125
        width: 129
        height: 111
        color: "#ffffff"
        border.width: 5
        border.color: "#000000"
    
        Text {
            id: button1_text
            x: 43
            y: 49
            text: qsTr("Button 1")
            font.pixelSize: 12
        }
    
        MouseArea {
            id: button1_mousearea
            anchors.fill: parent
            hoverEnabled: true
            onEntered: parent.border.color = "green"
            onExited: parent.border.color = "black"
            onClicked: {
                console.log("Trigger1 clicked")
    
                //send signal...
    
                main.trigger_signal("1")
    
            }
        }
    }
    

    }
    @

    main.cpp
    @
    #include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include "dialog.h"
    #include <QQuickItem>

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    //connect signal and slot...
    
    QQuickView
            view(QUrl::fromLocalFile&#40;"qml/2qml_Simpack_Trigger/main.qml"&#41;);
    QQuickItem *item = view.rootObject();
    
    Dialog dialog;
    
    QObject::connect(item, SIGNAL(trigger_signal(QString)), &dialog, SLOT(trigger_slot(QString)));
    
    view.show();
    
    return app.exec();
    

    }
    @

    dialog.h
    @
    #include <QObject>
    #include <iostream>
    #include <QDebug>

    using namespace std;

    #ifndef DIALOG_H
    #define DIALOG_H

    class Dialog: public QObject
    {
    Q_OBJECT

    public slots:

    //create slot...
    
    void trigger_slot(const QString &msg);
    

    };

    #endif // DIALOG_H
    @

    dialog.cpp
    @
    #include <QFile>
    #include <QProcess>
    #include "Dialog.h"
    #include <iostream>
    #include <QDebug>

    using namespace std;

    void Dialog::trigger_slot(const QString &msg)
    {
    cout << "Trigger empfangen" << endl;

    qDebug() << "Trigger received with number " << msg;
    

    }
    @


Log in to reply
 

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