Having used Qt for C++ applications for quite some time now I wanted to do my next project using QML. I now have the following scenario:
Now I want to be able to call C++ functions from my QML files ( green arrows ).
Content.qml
needs to read properties from WifiManager LiveField.qml
and GameField.qml
need to show / hide the corresponding C++ views I used C++ for the views because of some heavy 3D stuff which I'm not that familiar with in QML (I only used QML for the UI menu).
I'd rather not create the C++ classes from within my QML code using qmlRegisterType
since I need to do some initializing in my C++ code.
What is the best way to solve my problem?
C++ objects are typically shared using QQmlContext::setContextProperty
. You can find more information about QQmlContext here . This makes any object (or value) that you put in the context widely available.
Two words of caution though:
#include "wifimanager.h"
// That one is required
#include <QGuiApplication>
#include <QQmlContext>
#include <QQmlApplicationEngine>
void main() {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
WifiManager wifi;
engine.rootContext().setContextProperty("wifiManager", &wifi);
engine.load(QUrl("qrc:/main.qml"));
return app.exec();
}
You can then use wifiManager
on the QML side, along with its slots
, Q_PROPERTY
ies, and signals
As with regular QML, you can now bind and read your object's properties.
var value = wifiManager.value
someProperty: wifiManager.value
Any QML binding will be re-evaluated automatically whenever the value changes, as long as you emit the associated NOTIFY
signal. For example:
Q_PROPERTY(QString ssid READ ssid WRITE setSsid NOTIFY ssidChanged)
Text {
// Calls the READ getter of your Q_PROPERTY
// Will automatically update whenever the SSID changes
text: wifiManager.ssid
}
As easy as reading the value, you can write to it by doing wifiManager.ssid = xxx
Button {
text: "Reset SSID"
onClicked: {
// Calls the WRITE setter of your Q_PROPERTY
wifiManager.ssid = ""
}
}
Signals can be handled with the Connections
object. As with any QML object, you have to prefix your signal's name with on
and a capital letter. Which gives onWifiConnected: {}
for signal void wifiConnected();
Connections {
target: wifiManager
// Handle `wifiConnected` signal
onWifiConnected: {
console.log("Connected!")
// If your `wifiConnected` signal has an argument named `ip`
// it will be available here under the same name
console.log("My IP is", ip)
}
}
Slots and Q_INVOKABLE
s are accessible as any other functions in javascript. So you can call wifiManager.disconnect()
Button {
text: "disconnect"
onClicked: {
// Calls the `disconnect` slot or Q_INVOKABLE
wifiManager.disconnect()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.