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 ?
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.
Comments