QML variable itegrated from C++ (property?)
-
Hello gurus,
I have already asked similar question, but because i was too lost, with options, better would be starting newone because after reframing the basic idea, i guess the proposed solution would be way easier...
so lets say I have this in QML:
property bool someVariable
and via QML Timer, onTick i update the variable from c++ function:
onTriggered: { someVariable = cpp.variableRefresh(); }
in c++, i have the class registered:
qmlRegisterType<CPP>("CPP", 1, 0, "CPP");
and the boolean in the CPP class is:
bool variableRefresh() { return true; }
So as I can asume this is very silly way to update someVariable from QML via C++,
but if I wish to go otherway around, something like:void variableRefresh() { QML.someVariable = true; }
Is there a way to do it?
Can setContextProperty() or setProperty() be used?
I have tried to google this all day long, but at the end of the day I have to ask because it made me even more confused... -
@LeLev said in QML variable itegrated from C++ (property?):
How and where do you create object from MSSQL class ?
Im creating a c++ instance of MSSQL class,
so basicaly, I declare the MSSQL class from main.cpp via:
qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL");
then in QML I load it via:
MSSQL { id: sql }
and from QML I declare then variable:
property bool dbOnline
which im updating via:
dbOnline = sql.checkConnection();
to summary, the whole code is:
main.cpp:#include <QQmlApplicationEngine> #include <QGuiApplication> #include <QtQml> #include <QCoreApplication> #include <QtCore> #include <QtSql> #include <QtDebug> #include "mssql.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); engine.load(url); return app.exec(); }
main.qml:
import QtQuick 2.12 import QtQuick.Controls 2.0 import MSSQL 1.0 ApplicationWindow { id: mainWindow property bool dbOnline MSSQL { id: sql } Timer { id: dbRefresh interval: 30000 running: true repeat: true onTriggered: { dbOnline=sql.checkConnection(); } } }
mssql.h:
#ifndef MSSQL_H #define MSSQL_H #include <QObject> #include <QSqlDatabase> class MSSQL : public QObject { Q_OBJECT public: explicit MSSQL(QObject *parent = nullptr); Q_INVOKABLE bool checkConnection(); private: signals: public slots: }; #endif // MSSQL_H
mssql.cpp:
#include <QtSql> #include <QSqlQuery> #include <QSqlDatabase> #include "main.cpp" #include "mssql.h" MSSQL::MSSQL(QObject *parent) : QObject(parent) { } bool MSSQL::checkConnection() { if(something) { // here I need to change the QML variable dbOnline to: true return true; } else { // here I need to change the QML variable dbOnline to: false return false; } }
@shokarta said in QML variable itegrated from C++ (property?):
Im creating a c++ instance of MSSQL class,
so basicaly, I declare the MSSQL class from main.cpp via:
qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL");you are Registering a new QML type
@shokarta said in QML variable itegrated from C++ (property?):
ApplicationWindow {
id: mainWindow
property bool dbOnlineMSSQL { id: sql }
and here you create an instance of your object in QML.
you can simply do like this
ApplicationWindow { id: mainWindow property bool dbOnline : sql.isOnline // < bind your property dbOnline to Qproperty of your object MSSQL { id: sql } Timer { id: dbRefresh interval: 30000 running: true repeat: true onTriggered: { dbOnline=sql.checkConnection(); } } }
and in checkConnection method you assign the qpoperty
void MSSQL::checkConnection(){ ... setIsOnline(true or false ) }
-
All QML components are QObjects. You can get the root QObject of your QML scene, find your desired QML object, and manipulate it via setProperty() as you wish.
However, in most cases, it is completely unnecessary to do so.
If you have a property or variable which changes from time to time, make it into a property (
Q_PROPERTY
withNOTIFY
signal). Expose that object to QML and react to it changing (onYourSignalName
handler). This way you:- don't need a timer at all
- change the value in QML only when it actually changes (big performance gain!), instead of calling the same method via meta object system periodically
-
@sierdzio said in QML variable itegrated from C++ (property?):
make it into a property (Q_PROPERTY with NOTIFY signal). Expose that object to QML and react to it changing (onYourSignalName handler)
Can I kindly ask you to show me code how can I do this?
This will be the first time I would do so, so I wish to learn how to do this properly, this would be an extreme gain for my practice and I can see the benefit of modifying my apps this way -
@sierdzio said in QML variable itegrated from C++ (property?):
make it into a property (Q_PROPERTY with NOTIFY signal). Expose that object to QML and react to it changing (onYourSignalName handler)
Can I kindly ask you to show me code how can I do this?
This will be the first time I would do so, so I wish to learn how to do this properly, this would be an extreme gain for my practice and I can see the benefit of modifying my apps this way@shokarta Easy to find using Google: https://doc.qt.io/qt-5/properties.html
-
im sorry i just dont understand how can i implement that whatsoever.
According to https://stackoverflow.com/questions/27584803/how-to-set-qml-properties-from-c
it seems simple to implement this, but only from main.cpp from main().
But when I need to change the property from my custom class, then im just lost...is it too much to ask for example based on my scenario?
That way I can understand the better then just blindly keep trying something which makes no sence to me :(main.cpp
#include <QQmlApplicationEngine> #include <QGuiApplication> #include <QtQml> #include <QCoreApplication> #include <QtCore> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QtSql> #include <QtDebug> #include <QTextStream> #include "mssql.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
mssql.h:
#ifndef MSSQL_H #define MSSQL_H #include <QObject> #include <QSqlDatabase> class MSSQL : public QObject { Q_OBJECT public: explicit MSSQL(QObject *parent = nullptr); Q_INVOKABLE bool checkConnection(bool skipRefresh = false); private: signals: public slots: }; #endif // MSSQL_H
mssql.cpp:
#include <QtSql> #include <QSqlQuery> #include <QObject> #include <QSqlDatabase> #include "main.cpp" #include <QSettings> #include <QtDebug> #include "mssql.h" #include <QQmlComponent> MSSQL::MSSQL(QObject *parent) : QObject(parent) { } bool MSSQL::checkConnection(bool skipRefresh) { //here I have to modify the QML property mainWindow.dbOnline = true; }
main.qml:
import QtQuick 2.12 import QtQuick.Controls 2.0 import MSSQL 1.0 ApplicationWindow { id: mainWindow property bool dbOnline //this to be updated from c++ checkConnection() .... }
-
im sorry i just dont understand how can i implement that whatsoever.
According to https://stackoverflow.com/questions/27584803/how-to-set-qml-properties-from-c
it seems simple to implement this, but only from main.cpp from main().
But when I need to change the property from my custom class, then im just lost...is it too much to ask for example based on my scenario?
That way I can understand the better then just blindly keep trying something which makes no sence to me :(main.cpp
#include <QQmlApplicationEngine> #include <QGuiApplication> #include <QtQml> #include <QCoreApplication> #include <QtCore> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QtSql> #include <QtDebug> #include <QTextStream> #include "mssql.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
mssql.h:
#ifndef MSSQL_H #define MSSQL_H #include <QObject> #include <QSqlDatabase> class MSSQL : public QObject { Q_OBJECT public: explicit MSSQL(QObject *parent = nullptr); Q_INVOKABLE bool checkConnection(bool skipRefresh = false); private: signals: public slots: }; #endif // MSSQL_H
mssql.cpp:
#include <QtSql> #include <QSqlQuery> #include <QObject> #include <QSqlDatabase> #include "main.cpp" #include <QSettings> #include <QtDebug> #include "mssql.h" #include <QQmlComponent> MSSQL::MSSQL(QObject *parent) : QObject(parent) { } bool MSSQL::checkConnection(bool skipRefresh) { //here I have to modify the QML property mainWindow.dbOnline = true; }
main.qml:
import QtQuick 2.12 import QtQuick.Controls 2.0 import MSSQL 1.0 ApplicationWindow { id: mainWindow property bool dbOnline //this to be updated from c++ checkConnection() .... }
#ifndef MSSQL_H #define MSSQL_H #include <QObject> class MSSQL : public QObject { Q_OBJECT Q_PROPERTY(bool isOnline READ isOnline WRITE setIsOnline NOTIFY isOnlineCHanged) public: explicit MSSQL(QObject *parent = nullptr); bool isOnline()const{ return m_isOnline; } void setIsOnline(const bool &onLine){ if(m_isOnline==onLine)return; m_isOnline = onLine; emit isOnlineCHanged(/*m_isOnline*/); } signals: void isOnlineCHanged(/*bool*/); private : bool m_isOnline=false; }; #endif // MSSQL_H
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "mssql.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; MSSQL myDb; engine.rootContext()->setContextProperty("myDatabase",&myDb); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") property bool dbOnline : myDatabase.isOnline onDbOnlineChanged: console.log("database is", dbOnline ? "online" : "offline") Button{ text: "test" onClicked: myDatabase.isOnline = !myDatabase.isOnline } }
-
Hello, and thanks a lot!
mostly I do understand it quite alright, however what I do not understand is:
engine.rootContext()->setContextProperty("myDatabase",&myDb);
- this obviously throws error: use of undeclared identifier 'myDb'
and also still dont understand how will change the QML variable from mssql.cpp, speficifly from this bool/void:
bool MSSQL::checkConnection(bool skipRefresh) { //here I have to modify the QML property mainWindow.dbOnline = true; }
- because here i have some code, which returns true/false because i update the value like dbOnline=MSSQL::checkConnection(),
- but if i change it to be void, then anytime i wish to update the dbOnline, i can do it directly from this c++ function
-
Hello, and thanks a lot!
mostly I do understand it quite alright, however what I do not understand is:
engine.rootContext()->setContextProperty("myDatabase",&myDb);
- this obviously throws error: use of undeclared identifier 'myDb'
and also still dont understand how will change the QML variable from mssql.cpp, speficifly from this bool/void:
bool MSSQL::checkConnection(bool skipRefresh) { //here I have to modify the QML property mainWindow.dbOnline = true; }
- because here i have some code, which returns true/false because i update the value like dbOnline=MSSQL::checkConnection(),
- but if i change it to be void, then anytime i wish to update the dbOnline, i can do it directly from this c++ function
@shokarta said in QML variable itegrated from C++ (property?):
engine.rootContext()->setContextProperty("myDatabase",&myDb);
this obviously throws error: use of undeclared identifier 'myDb'
How and where do you create object from MSSQL class ?
@shokarta said in QML variable itegrated from C++ (property?):
and also still dont understand how will change the QML variable from mssql.cpp, speficifly from this bool/void:
use the setter method (WRITE)
Q_PROPERTY(bool isOnline READ isOnline WRITE setIsOnline NOTIFY isOnlineCHanged)
setIsOnline(yourValue)
then
isOnlineCHanged signal will be emitted (NOTIFY )
because setIsOnline is defined like thisvoid setIsOnline(const bool &onLine){ if(m_isOnline==onLine)return; m_isOnline = onLine; emit isOnlineCHanged(/*m_isOnline*/); }
then qml will be updated automatically
property bool dbOnline : myDatabase.isOnlinereading the documentation linked by jsulm and sierdzio might help
-
@LeLev said in QML variable itegrated from C++ (property?):
How and where do you create object from MSSQL class ?
Im creating a c++ instance of MSSQL class,
so basicaly, I declare the MSSQL class from main.cpp via:
qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL");
then in QML I load it via:
MSSQL { id: sql }
and from QML I declare then variable:
property bool dbOnline
which im updating via:
dbOnline = sql.checkConnection();
to summary, the whole code is:
main.cpp:#include <QQmlApplicationEngine> #include <QGuiApplication> #include <QtQml> #include <QCoreApplication> #include <QtCore> #include <QtSql> #include <QtDebug> #include "mssql.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); engine.load(url); return app.exec(); }
main.qml:
import QtQuick 2.12 import QtQuick.Controls 2.0 import MSSQL 1.0 ApplicationWindow { id: mainWindow property bool dbOnline MSSQL { id: sql } Timer { id: dbRefresh interval: 30000 running: true repeat: true onTriggered: { dbOnline=sql.checkConnection(); } } }
mssql.h:
#ifndef MSSQL_H #define MSSQL_H #include <QObject> #include <QSqlDatabase> class MSSQL : public QObject { Q_OBJECT public: explicit MSSQL(QObject *parent = nullptr); Q_INVOKABLE bool checkConnection(); private: signals: public slots: }; #endif // MSSQL_H
mssql.cpp:
#include <QtSql> #include <QSqlQuery> #include <QSqlDatabase> #include "main.cpp" #include "mssql.h" MSSQL::MSSQL(QObject *parent) : QObject(parent) { } bool MSSQL::checkConnection() { if(something) { // here I need to change the QML variable dbOnline to: true return true; } else { // here I need to change the QML variable dbOnline to: false return false; } }
-
@LeLev said in QML variable itegrated from C++ (property?):
How and where do you create object from MSSQL class ?
Im creating a c++ instance of MSSQL class,
so basicaly, I declare the MSSQL class from main.cpp via:
qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL");
then in QML I load it via:
MSSQL { id: sql }
and from QML I declare then variable:
property bool dbOnline
which im updating via:
dbOnline = sql.checkConnection();
to summary, the whole code is:
main.cpp:#include <QQmlApplicationEngine> #include <QGuiApplication> #include <QtQml> #include <QCoreApplication> #include <QtCore> #include <QtSql> #include <QtDebug> #include "mssql.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); engine.load(url); return app.exec(); }
main.qml:
import QtQuick 2.12 import QtQuick.Controls 2.0 import MSSQL 1.0 ApplicationWindow { id: mainWindow property bool dbOnline MSSQL { id: sql } Timer { id: dbRefresh interval: 30000 running: true repeat: true onTriggered: { dbOnline=sql.checkConnection(); } } }
mssql.h:
#ifndef MSSQL_H #define MSSQL_H #include <QObject> #include <QSqlDatabase> class MSSQL : public QObject { Q_OBJECT public: explicit MSSQL(QObject *parent = nullptr); Q_INVOKABLE bool checkConnection(); private: signals: public slots: }; #endif // MSSQL_H
mssql.cpp:
#include <QtSql> #include <QSqlQuery> #include <QSqlDatabase> #include "main.cpp" #include "mssql.h" MSSQL::MSSQL(QObject *parent) : QObject(parent) { } bool MSSQL::checkConnection() { if(something) { // here I need to change the QML variable dbOnline to: true return true; } else { // here I need to change the QML variable dbOnline to: false return false; } }
@shokarta said in QML variable itegrated from C++ (property?):
Im creating a c++ instance of MSSQL class,
so basicaly, I declare the MSSQL class from main.cpp via:
qmlRegisterType<MSSQL>("MSSQL", 1, 0, "MSSQL");you are Registering a new QML type
@shokarta said in QML variable itegrated from C++ (property?):
ApplicationWindow {
id: mainWindow
property bool dbOnlineMSSQL { id: sql }
and here you create an instance of your object in QML.
you can simply do like this
ApplicationWindow { id: mainWindow property bool dbOnline : sql.isOnline // < bind your property dbOnline to Qproperty of your object MSSQL { id: sql } Timer { id: dbRefresh interval: 30000 running: true repeat: true onTriggered: { dbOnline=sql.checkConnection(); } } }
and in checkConnection method you assign the qpoperty
void MSSQL::checkConnection(){ ... setIsOnline(true or false ) }