How to catch C++ signal in QML signal handler after type registration?

Jatin

I am developing a basic qml-cpp application to understand how one interacts with another. I have a MessageSetter C++ class and one main.qml. Since I wish to understand two-way communication, I exposed MessageSetter properties to qml using setContextProperty and also registered MessageSetter class with qml (instantiable registration). Exposed properties work fine. Now when a qml button is clicked, then the signal (qmlBtnClicked) is successfully caught in a MessageSetter slot(onQmlButtonClicked). This slot further emits another MessageSetter signal (colorChanged). This new (C++) signal should be caught in qml registered MessageSetter's signal handler (onColorChanged) but it does not arrive here in any case. Below is main.cpp code:

int main(int argc, char *argv[])
{
   QGuiApplication app(argc, argv);
   QQmlApplicationEngine engine;
   qmlRegisterType<MessageSetter>("com.SkillLotto.MessageSetter", 1, 0, "SetMessage");

   MessageSetter data;
   engine.rootContext()->setContextProperty("msgSetter", &data);
   QQmlComponent component(&engine, QUrl::fromLocalFile("main.qml"));

   QObject *object = component.create()->findChild<QObject*>("setTextBtn");
   QObject::connect(object, SIGNAL(qmlBtnClicked()), &data, SLOT(onQmlButtonClicked()));

   return app.exec();
}

This is MessageSetter slot that emits another signal:

void MessageSetter::onQmlButtonClicked()
{
   emit colorChanged("red");
}

This is qml code, this signal handler never gets called:

SetMessage{
    onColorChanged: {
        rect.color = color    //rect is some rectangle in this file.
    }
}

As I stated, qml signal is successfully caught in C++ slot but I am unable to catch this C++ signal in qml signal handler. Any help please.

This question, as I see, is focussed on qmlRegisterType() and should not be duplicate of this question? I also want to know whether qmlRegisterType() and setContextProperty() cant be used simultaneously or not ?

Tarod

I think your code should work well.

I don't have the whole code so I don't know if you have the right methods implemented.

In order to get the signal using qmlRegisterType you need some requirements. Check if you have the Q_PROPERTY macro call implemented. Any property that is writable should have an associated NOTIFY signal that is emitted whenever the property value has changed.

If so, when you change the color property in the SetMessage component, the signal onColorChanged should be triggered.

Here you have an example where two signals are emitted: the first one when the size property is updated and the second one if the C++ mouseClick method is called using a MouseArea.

By the way, you don't need setContextProperty to integrate your C++ class with QML. qmlRegisterType should be enough. Or vice versa, depending on your needs. You can use both, but then you will have two different objects to work with. It really depends on what you want to achieve.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "customitem.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    qmlRegisterType<CustomItem>("CustomItem", 1,0, "CustomItem");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

customitem.h

#ifndef CUSTOMITEM_H
#define CUSTOMITEM_H

#include <QObject>

class CustomItem: public QObject
{
    Q_OBJECT

    /*
     * Any property that is writable should have an associated NOTIFY signal.
     * Ref: http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html#exposing-properties
     */

    Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)

public:
    CustomItem(QObject *parent = 0);

    int size() const;
    void setSize(int);

    Q_INVOKABLE void mouseClick();

private:
    int m_size;

signals:
    void sizeChanged(int size);
    void clicked();

public slots:
};

#endif // CUSTOMITEM_H

customitem.cpp

#include "customitem.h"
#include <QDebug>

CustomItem::CustomItem(QObject *parent)
: QObject(parent), m_size(0)
{
}

int CustomItem::size() const
{
    return m_size;
}

void CustomItem::setSize(int size)
{
    m_size = size;
    emit sizeChanged(m_size);
}

void CustomItem::mouseClick()
{
    qDebug() << "CustomItem::mouseClick()";

    emit clicked();
}

main.qml

import QtQuick 2.5
import QtQuick.Window 2.2
import CustomItem 1.0

Window {
    visible: true

    TextInput  {
        id: mySize
        x: 0
        y: 0
        text: "100"
    }

    CustomItem {
        id: customItem
        size: mySize.text

        onSizeChanged: console.log("size changed:", size)
        onClicked: console.log("onClicked!")
    }

    Rectangle {
        id: rect
        x: 50
        y: 50
        width: customItem.size
        height: customItem.size
        color: "red"

        MouseArea {
            anchors.fill: parent
            onClicked: { customItem.mouseClick() }
        }
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to catch C++ signal in QML signal handler after type registration?

From Dev

How to catch a signal properly in C

From Dev

How to avoid scanf after my signal handler function in C?

From Dev

How to use a custom Qt type with a QML signal?

From Dev

How to set property type of qml signal?

From Dev

How to set property type of qml signal?

From Dev

c Signal Handler

From Java

How to catch custom exception from signal handler in asyncio?

From Dev

Setting signal handler for any signal in C

From Dev

Setting signal handler for any signal in C

From Dev

QML: Overriding a signal handler from other element

From Dev

Signal Handler to stop Timer in C

From Dev

How to register a signal handler for a subprocess?

From Dev

how to alternate continously Signal handler

From Dev

QML - connect a signal from c++ to qml

From Dev

How to get signal to catch SIGABRT

From Dev

How to connect a qml child component signal to a c++ slot

From Dev

How can I listen to a C++ signal from QML?

From Dev

boost::asio signal_set handler only executes after first signal is caught and ignores consecutive signals of the same type

From Dev

boost::asio signal_set handler only executes after first signal is caught and ignores consecutive signals of the same type

From Dev

Why signal handler for SIGSEGV doesn't catch my C++ throw exception?

From Dev

C++ using signal slots for QML

From Dev

Fail To Connect Qml signal to C++ Slot

From Dev

timer_create() not able to catch a signal in handler function

From Dev

Why won't this signal handler catch SIGHUP or SIGQUIT?

From Dev

How to override signal handler of superclass component

From Dev

How do I create a signal handler in elisp?

From Java

How to avoid using printf in a signal handler?

From Dev

How to register a signal handler as a class method?

Related Related

  1. 1

    How to catch C++ signal in QML signal handler after type registration?

  2. 2

    How to catch a signal properly in C

  3. 3

    How to avoid scanf after my signal handler function in C?

  4. 4

    How to use a custom Qt type with a QML signal?

  5. 5

    How to set property type of qml signal?

  6. 6

    How to set property type of qml signal?

  7. 7

    c Signal Handler

  8. 8

    How to catch custom exception from signal handler in asyncio?

  9. 9

    Setting signal handler for any signal in C

  10. 10

    Setting signal handler for any signal in C

  11. 11

    QML: Overriding a signal handler from other element

  12. 12

    Signal Handler to stop Timer in C

  13. 13

    How to register a signal handler for a subprocess?

  14. 14

    how to alternate continously Signal handler

  15. 15

    QML - connect a signal from c++ to qml

  16. 16

    How to get signal to catch SIGABRT

  17. 17

    How to connect a qml child component signal to a c++ slot

  18. 18

    How can I listen to a C++ signal from QML?

  19. 19

    boost::asio signal_set handler only executes after first signal is caught and ignores consecutive signals of the same type

  20. 20

    boost::asio signal_set handler only executes after first signal is caught and ignores consecutive signals of the same type

  21. 21

    Why signal handler for SIGSEGV doesn't catch my C++ throw exception?

  22. 22

    C++ using signal slots for QML

  23. 23

    Fail To Connect Qml signal to C++ Slot

  24. 24

    timer_create() not able to catch a signal in handler function

  25. 25

    Why won't this signal handler catch SIGHUP or SIGQUIT?

  26. 26

    How to override signal handler of superclass component

  27. 27

    How do I create a signal handler in elisp?

  28. 28

    How to avoid using printf in a signal handler?

  29. 29

    How to register a signal handler as a class method?

HotTag

Archive