.property('objectName') always returns empty string
-
wrote on 17 Jul 2022, 11:41 last edited by
I'm wanting to iterate over all objects within the rootObject (getting objectName of each child in the process). I have the following code which appears to read some properties back, but for some reason, property objectName always returns an empty string. Also, could someone explain the "hidden" QObjects that print out which are not in the QML.
import os from pathlib import Path import sys from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QObject if __name__ == "__main__": app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml")) rootObject = engine.rootObjects()[0] objList = rootObject.findChildren(QObject, "") for object in objList: print(object) print("objectName: " + object.property('objectName')) print("width: " + str(object.property('width'))) sys.exit(app.exec())
QML:
import QtQuick import QtQuick.Window import QtQuick.Controls Window { objectName: "window" width: 540 height: 700 visible: true color: "#ffffff" title: qsTr("Calc") Button { objectName: "button1" id: b1 width: 120 height: 80 text: qsTr("7") flat: false highlighted: false font.bold: true font.pointSize: 12 } }
Console Output:
<PySide6.QtCore.QObject(0x220a0511020) at 0x00000220A0780940> objectName: width: 540.0 <PySide6.QtCore.QObject(0x220a16dcde0) at 0x00000220A0818D40> objectName: width: None <PySide6.QtCore.QObject(0x220a0519960) at 0x00000220A0818B80> objectName: width: 120.0 <PySide6.QtCore.QObject(0x220a15ddf70) at 0x00000220A0818BC0> objectName: width: None <PySide6.QtCore.QObject(0x220a15eeb70) at 0x00000220A0818CC0> objectName: width: 120.0 <PySide6.QtCore.QObject(0x2209e682ec0) at 0x00000220A0818C00> objectName: width: 112.0
-
Hi,
Just I wild guess, but I think that you are requesting the objects too early in the process. The QML side is likely not yet fully loaded.
What about using the objectCreated signal ?
-
Hi,
Just I wild guess, but I think that you are requesting the objects too early in the process. The QML side is likely not yet fully loaded.
What about using the objectCreated signal ?
wrote on 17 Jul 2022, 13:42 last edited by WoR473@SGaist Thank you for the response.
Unfortunately this doesn't appear to be the cause (assuming the changes that i made had the desired effect, which it appears they did to my noob eyes).
# This Python file uses the following encoding: utf-8 import os from pathlib import Path import sys from time import sleep from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QObject, QTimer if __name__ == "__main__": app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml")) rootObject = engine.rootObjects()[0] objList = rootObject.findChildren(QObject, '') def printObjNames(): for object in objList: print(object) print("objectName: " + object.property('objectName')) print("width: " + str(object.property('width'))) QTimer().singleShot(3000, printObjNames) sys.exit(app.exec())
Console output is identical to first post, with the exception of the 3 second delay before it appears.
-
wrote on 17 Jul 2022, 14:18 last edited by
I tried utilizing the objectCreated signal, i'm not sure i've done this right, i can't find any examples of using this signal and i'm not "up" on slots/signals yet. newObj() never runs so if i've set this up right it appears that it never gets done loading?
import os from pathlib import Path import sys from time import sleep from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QObject, QTimer if __name__ == "__main__": app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml")) rootObject = engine.rootObjects()[0] objList = rootObject.findChildren(QObject, '') def printObjNames(): for object in objList: print("objectName: " + object.property('objectName')) print("width: " + str(object.property('width'))) def newObj(): print("loaded new obj") engine.objectCreated.connect(newObj) QTimer().singleShot(3000, printObjNames) sys.exit(app.exec())
-
wrote on 17 Jul 2022, 14:37 last edited by WoR473
Disregard my prev post, i must be doing something wrong there. I did find that if i specify the object name in .findChildren, then it returns the object with the objectName, but for some reason if i just try to grab all the children, then iterate through them, that does not work.
import os from pathlib import Path import sys from time import sleep from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QObject, QTimer if __name__ == "__main__": app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml")) rootObject = engine.rootObjects()[0] objList = rootObject.findChildren(QObject, '') for object in objList: print(object) print("objectName: " + object.property('objectName')) print("width: " + str(object.property('width'))) objList = rootObject.findChildren(QObject, 'button1') for object in objList: print(object) print("objectName: " + object.property('objectName')) print("width: " + str(object.property('width'))) sys.exit(app.exec())
Console Output:
<PySide6.QtCore.QObject(0x1d998384480) at 0x000001D997519180> objectName: width: 540.0 <PySide6.QtCore.QObject(0x1d9983942d0) at 0x000001D997518F40> objectName: width: None <PySide6.QtCore.QObject(0x1d9982f4240) at 0x000001D997518FC0> objectName: width: 120.0 <PySide6.QtCore.QObject(0x1d9982ec280) at 0x000001D997519000> objectName: width: None <PySide6.QtCore.QObject(0x1d9983123d0) at 0x000001D997519100> objectName: width: 120.0 <PySide6.QtCore.QObject(0x1d9984ac540) at 0x000001D997519080> objectName: width: 112.0 <PySide6.QtCore.QObject(0x1d9958b2240, name = "button1") at 0x000001D997518F00> objectName: button1 width: 120.0
-
wrote on 17 Jul 2022, 15:05 last edited by WoR473
I found that removing the string completely (instead of using an empty string) did the trick. I'm not sure why i thought that would work in the first place, i think it was one of those lets try it and see what happens and i had objects coming back so i assumed i was iterating over everything there.
Instead of:
objList = rootObject.findChildren(QObject, '')
This:
objList = rootObject.findChildren(QObject)
Console Output:
<PySide6.QtCore.QObject(0x1d9374b9e80) at 0x000001D9390F90C0> objectName: width: 540.0 <PySide6.QtCore.QObject(0x1d939f97080) at 0x000001D9390F8EC0> objectName: width: None <PySide6.QtCore.QObject(0x1d9374eade0, name = "button1") at 0x000001D9390F8F40> objectName: button1 width: 120.0 <PySide6.QtCore.QObject(0x1d939fda1d0) at 0x000001D9390F8F80> objectName: width: 120.0 <PySide6.QtCore.QObject(0x1d939eee640) at 0x000001D9390F9040> objectName: width: None <PySide6.QtCore.QObject(0x1d939fda050) at 0x000001D9390F8FC0> objectName: width: 120.0 <PySide6.QtCore.QObject(0x1d9374e9720) at 0x000001D9390F9000> objectName: width: 112.0 <PySide6.QtCore.QObject(0x1d939fbfde0, name = "label") at 0x000001D9390F8F00> objectName: label width: 9.0
I assume that by specifying an empty string it is finding components with no objectName set, but what is curious to me still is what are these mystery components?
-
I knew that empty string was nagging me for a reason...
There are several QObjects that can be created as part of the object tree that supports your application.
1/7