C++ signal to a QML file
-
Hello,
I'm still learning about signals and slots. With a signal from C++ to QML , rather than calling a certain slot (function) in the QML file, is it possible to call and run all the code in a qml file?
//.qml function callCPP(key) { var value= myGlobalObject.readJson(key) return value } speedt.text: callCPP("Engine_Spd") power.text: callCPP("Engine_Power") . . .
sparing all the details... I have a file watcher set up in my C++ and when a change is made I want to call the qml file, so that all of the text boxes get updated with the new correct data. The function calls are just statements in the qml file, so I'm wondering how I can run through them all when a signal is emitted from C++??
Also, any tips on signals and slots are more than welcomed! thanks. -
@texasRanger Hey,
If you want to "run" a qml file, you have to create it dynamicly, not the best idea if all you want is to update labels..
You can emit a signal(signalFromChanged();) from the slot you have connected the filewatchers fileChanged signal to, then receive the update through onSignalFromChanged: {} in qml. Then in onSignalFromChanged you can call the function from your qml file.
To do this you must register the C++ file as a qml type in main.cpp with;
-----------------FileWatcher.h--import statement, major, minor - qml typeqmlRegisterType<FileWatcher>("libFileWatcher", 1, 0, "FileWatcherClass");
Then in the QML file you can do:
import libFileWatcher 1.0 FileWatcherClass { id: fileWatcher onSignalFromChanged: { speedt.text=callCPP("Engine_Spd"); power.text=callCPP("Engine_Power"); } }
The cpp file must have a Q_PROPERTY reading the json list, which makes you able to use the function callCPP to read a object from the QJsonObject Class with
fileWatcher.readJson.find(key);
Hope this helps you get started
-
@texasRanger said in C++ signal to a QML file:
C++ to QML
One way to react to c++ signal in QML is using QML Connection type.
first expose the instance of your object to QML using Context Property//cpp signals: void changeMade() //qml Connections { target: yourObject onChangeMade { // js } }
-
It is also possible to connect a C++ signal to a QML "slot" from the C++ side: https://doc.qt.io/qt-5/signalsandslots-syntaxes.html#connecting-c-objects-to-qml-objects
Note that any arguments must the
QVariant
type:class CppGui : public QWidget { Q_OBJECT QPushButton *button; signals: void cppSignal(const QVariant& sentMsg) const; public: CppGui(QWidget *parent = nullptr) : QWidget(parent) { button = new QPushButton("Click Me!", this); connect(button, &QPushButton::clicked, [=] { emit cppSignal("Hello from C++!"); }); } };
// QmlGui.qml Rectangle { width: 100; height: 100 function qmlSlot(receivedMsg) { console.log("QML received: " + receivedMsg) } }
auto cppObj = new CppGui(this); auto quickWidget = new QQuickWidget(QUrl("QmlGui.qml"), this); auto qmlObj = quickWidget->rootObject(); // Connect C++ signal to QML slot connect(cppObj, SIGNAL(cppSignal(QVariant)), qmlObj, SLOT(qmlSlot(QVariant)));