Solved 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-elementsrootitem->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: 16signal qmlSignal(string msg) onClicked: switch1.qmlSignal("on") }
so i hope you can help me!
Thanks. -
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! -
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.