2016-12-07 2 views
1

я хочу найти любой объект по Objectname имени строки внутри от QApplicationНайти элемент в QApplication только в ObjectName

Что-то вроде

QApplication.instance().findByClassName("codeEditor") 

, который должен возвращать список виджетов с этим именем класса, который я могу перебрать, если есть более одного

[QPushButton (QPushButton at: 0x0000008EA3B3DD80), QWidget (QWidget at: 0x0000008EA3F33F40)] 

Я прочитал this но это требует объект и я хочу что-то вроде *

Это то, что я придумал для тестирования:

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") 

{}

enter image description here

+0

так (почти) все происходит от 'QObject' искать этот тип класса –

+0

@SebastianLange Что вы имеете в виду? – Bluscream

+0

@SebastianLange https://snag.gy/md8M7Y.jpg – Bluscream

ответ

1

Я придумал это, что хорошо работает

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 
+0

'allWidgets' обязательно включает' topLevelWidgets'. Используйте один или другой, а не оба. –

+0

Ни одна из этих функций не работает. Для первого, 'str (x .__ class __)' вернет нечто вроде '' "', поэтому он, очевидно, никогда не будет соответствовать. Вам нужно использовать 'x .__ class __.__ name__', но даже тогда это не будет соответствовать подклассам. Для второй функции вам нужно использовать' str (x.objectName()) ', иначе он никогда не будет соответствовать чему-либо. И обратите внимание, что обе функции вернут только первый найденный объект, а не список всех совпадающих объектов (что и задает вопрос). – ekhumoro

+0

Изменения, которые вы сделанный не исправить ни одной из проблем. – ekhumoro

0

Невозможно найти все QObject экземпляров в целом. Qt не отслеживает их, поскольку объекты могут использоваться в нескольких потоках, а накладные расходы на их отслеживание неоправданно высоки.

Qt отслеживает все виджеты, поскольку виджеты могут существовать только в основном потоке, и они являются довольно тяжелыми объектами, поэтому их отслеживание имеет сравнительно небольшие накладные расходы.

Итак, вы можете искать все виджеты, которые вы получаете от QApp.allWidgets(), и всех своих детей. Вы также можете просматривать дочерние объекты, к которым у вас есть доступ. Но если данный объект без родителя или не принадлежит виджету, то вы не найдете его таким образом.

+0

Я подумал о каком-то селекторе, например, если вы хотите найти dom в jquery '$ ('someElement')' – Bluscream

+0

@Bluscream Да. Итак? Я думал обо всех вещах. есть вопрос или комментарий к этому ответу? Говорить, что вы думали о чем-то случайном, не помогает. –

+0

Если вы считаете, что вам нужен глобальный поиск объектов, вы делаете это неправильно. Следите за предметами, которые вам нужны: вы иметь лучшие ресурсы для хорошей работы. Рамки помогут вам , но он не сделает этого для вас, так как его дизайн не может предвидеть ваши обстоятельства. –

1

В Python это можно сделать для любого класса, используя gc module. Он предоставляет метод для получения ссылок на все объекты, отслеживаемые сборщиком мусора. Очевидно, это довольно неэффективный подход, но он (почти) гарантирует, что любой тип объекта может быть найден.

Вот функция, чтобы получить список всех 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 
+0

Это хороший подход, но для меня это не работает: http://i.imgur.com/HreomDd.png – Bluscream

+0

@Bluscream. Почему вы ожидаете, что он будет работать, если вы не создадите экземпляры 'QObject'? Очевидно, вам нужно запустить его в том же интерпретаторе python, где были созданы объекты. – ekhumoro

+0

Но я хочу искать существующие объекты, а не те, которые я создал, очевидно ... – Bluscream