Найти элемент в QApplication только по имени объекта
Я хочу найти любой объект по имени строки имени объекта внутри QApplication
Что-то вроде
QApplication.instance().findByClassName("codeEditor")
который должен вернуть список виджетов с этим именем класса, который я могу перебрать, если их больше одного
[QPushButton (QPushButton at: 0x0000008EA3B3DD80), QWidget (QWidget at: 0x0000008EA3F33F40)]
Я прочитал это, но это требует объекта, и я хочу что-то вроде *
Это то, что я придумал для тестирования:
def findWidget(name):
name = name.lower()
widgets = self.topLevelWidgets()
widgets = widgets + self.allWidgets()
ret = dict()
c = 0
for x in widgets:
c += 1
if name in x.objectName.lower() or name in str(x.__class__).lower():
ret["class:"+str(x.__class__)+str(c)] = "obj:"+x.objectName;continue
if hasattr(x, "text"):
if name in x.text.lower():
ret["class:"+str(x.__class__)+str(c)] = "obj:"+x.objectName
return ret
Он даже не находит 'InfoFrame', который явно там:
>>> widget("info")
{}
3 ответа
Я пришел с этим, который работает довольно хорошо
def getWidgetByClassName(name):
widgets = QApplication.instance().topLevelWidgets()
widgets = widgets + QApplication.instance().allWidgets()
for x in widgets:
if name in str(x.__class__).replace("<class '","").replace("'>",""):
return x
def getWidgetByObjectName(name):
widgets = QApplication.instance().topLevelWidgets()
widgets = widgets + QApplication.instance().allWidgets()
for x in widgets:
if str(x.objectName) == name:
return x
def getObjects(name, cls=True):
import gc
objects = []
for obj in gc.get_objects():
if (isinstance(obj, PythonQt.private.QObject) and
((cls and obj.inherits(name)) or
(not cls and obj.objectName() == name))):
objects.append(obj)
return objects
В Python это можно сделать для любого класса с помощью модуля gc. Он предоставляет метод для получения ссылок на все объекты, отслеживаемые сборщиком мусора. Это, очевидно, довольно неэффективный подход, но он (почти) гарантирует, что любой тип объекта может быть найден.
Вот функция, чтобы получить список всех QObject
экземпляры по имени класса или имени объекта:
def getObjects(name, cls=True):
objects = []
for obj in gc.get_objects():
if (isinstance(obj, QtCore.QObject) and
((cls and obj.inherits(name)) or
(not cls and obj.objectName() == name))):
objects.append(obj)
return objects
Однако это всего лишь инструмент отладки - для большого приложения можно легко проверить несколько сотен тысяч объектов.
Если вам нужны только объекты, которые являются подклассами QWidget
, используйте эту функцию:
def getWidgets(name, cls=True):
widgets = []
for widget in QtGui.QApplication.allWidgets():
if ((cls and widget.inherits(name)) or
(not cls and widget.objectName() == name)):
widgets.append(widget)
return widgets
Не возможно найти все QObject
примеры в общем. Qt не отслеживает их, поскольку объекты могут использоваться в нескольких потоках, и издержки на их отслеживание будут излишне высокими.
Qt отслеживает все виджеты, так как виджеты могут существовать только в основном потоке, и они являются довольно тяжелыми объектами, поэтому отслеживание их имеет сравнительно небольшие накладные расходы.
Таким образом, вы можете искать все виджеты, которые вы получаете от QApp.allWidgets()
и всех их детей. Вы также можете просматривать дочерние объекты, к которым у вас есть доступ. Но если данный объект лишен родительских прав или не принадлежит виджету, вы не найдете его таким образом.