How can I access my control in windows qml type from C++ while using QQmlApplicationEngine?
-
here is my qml file ,very simple one. I have tried two ways to get pointer to my button but failed
Window {
id:mainWindow
objectName: "mainWindow"
visible: true
width: 480
height: 320
title: qsTr("Hello World")
Button {
id: button1
x: 0
y: 0
width: 173
height: 88
text: qsTr("Button")
}
}first I tried :
int main(int argc, char argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QObject rootObject = engine.rootObjects().first();
QObject * btn = rootObject->findChild<QObject*>("Button");
return app.exec();
}
but failed, btn is NULL.second , I tried this way( https://forum.qt.io/topic/83225/findchild-always-returns-null-looking-for-qml-objects/3 ):
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QQuickWindow * rootWindow = (QQuickWindow *)engine.rootObjects().first();
if (rootWindow)
rootWindow->setProperty("width", 1360);
QObject * btn = Q_NULLPTR;
auto list = rootWindow->contentItem()->childItems();
for (auto i : list) {
btn = i->findChild<QObject *>("Button"); //do not find ,btn is NULL
if (btn) break;
}return app.exec();
}
but failed, btn is NULL.so how could I access my control defined in qml file ?
-
@QtBeginnnnner said in How can I access my control in windows qml type from C++ while using QQmlApplicationEngine?:
btn = i->findChild<QObject *>("Button")
Button {
id: button1
objectName : "QtButton"}
Then do the following. It will work.
btn = i->findChild<QObject *>("QtButton")Not sure why you are doing this. It is not good practice.
-
@dheerendra hi dheerendra, I have modified my code to
Button {
id: idButton1
objectName: "objButton1"
...
text: qsTr("txtButton1")
}btn = i->findChild<QObject *>("objButton1");
but , still got a null pointer ..
and I'm doing this for preparation to transfer my app frame from wxwidget to QT/QML, any suggestions ? -
Try this
Window { id:mainWindow objectName: "mainWindow" visible: true width: 480 height: 320 title: qsTr("Hello World") Button { id: button1 x: 0 y: 0 width: 173 height: 88 text: qsTr("Button") objectName: "pthinks.com" } } int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; QObject *rootObj = engine.rootObjects().first(); qDebug() << Q_FUNC_INFO << rootObj->objectName() << endl; foreach (auto o1, rootObj->children()) { qDebug() << o1->objectName() << endl; } return app.exec(); }
-
@QtBeginnnnner
I think you're already too deep down the children tree to find the button,
try this:QQuickWindow * rootWindow = (QQuickWindow *)engine.rootObjects().first(); auto list = rootWindow->contentItem()->childItems(); for(QQuickItem *item : list) if(item->objectName() == "objButton1") qDebug() << "Found the button";
-
@dheerendra @J-Hilk
Thank you very much.
Finally , two ways to get pointer to my button both works , here is the code.import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.2
import QtQuick.Controls 1.4Window {
id:idWindow1
objectName: "objWindow1"
visible: true
width: 480
height: 320
title: qsTr("Hello World")Button { id: idButton1 objectName: "objButton1" x: 0 y: 0 width: 173 height: 88 text: qsTr("txtButton1") }
}
#include "mainwindow.h"
#include <QApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QPushButton>
#include <QQuickItem>//method 1 OK
int main(int argc, char *argv[]){
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty()) return -1;
QQuickWindow * rootWindow = (QQuickWindow *)engine.rootObjects().first();
if (rootWindow)
rootWindow->setProperty("width", 1360);
QObject * btn = Q_NULLPTR;
auto list = rootWindow->contentItem()->childItems();
for (QQuickItem *item : list) {
if (item->objectName() == "objButton1") {
qDebug() << "Found the button";
btn = item;
}
if (btn) break;
}
btn->setProperty("text", "textNew1");return app.exec();
}
//method 2 OK
int main(int argc, char argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QObject rootObject = engine.rootObjects().first();
QObject * btn = rootObject->findChild<QObject*>("objButton1");btn->setProperty( "text", "textNew2" ); return app.exec();
}
-
Don't do that.
Here are some resources to tell you why :) :
https://doc.qt.io/qt-5/qtquick-bestpractices.html#interacting-with-qml-from-c
http://doc.qt.io/qt-5/qtqml-cppintegration-overview.html#interacting-with-qml-objects-from-c
https://youtu.be/vzs5VPTf4QQ?t=23m20s