1

我想通过 QApplication 中的 objectname 字符串名称查找任何对象

就像是

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


{}

在此处输入图像描述

4

3 回答 3

1

在 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

PS

如果您想查找所有属于 的子类的对象,QObject则只有在您能够以某种方式确保应用程序中的所有实例都具有有效的父类(根据定义,它也必须是 a QObject)时才能实现。有了它,您就可以使用它root_object.findChildren(QObject)来获取完整列表。也可以使用findChildfindChildren按对象名称搜索单个对象(如果需要,可以选择使用正则表达式)。

于 2016-12-07T20:04:57.493 回答
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
于 2016-12-07T09:37:53.950 回答
0

一般来说,不可能找到所有QObject实例。Qt 不跟踪它们,因为对象可以在多个线程中使用,并且跟踪它们的开销会不必要地高。

不过,Qt 确实会跟踪所有小部件,因为小部件只能存在于主线程中,而且它们是相当重的对象,因此跟踪它们的开销相对较小。

因此,您可以搜索您从中获得的所有小部件QApp.allWidgets(),以及它们的所有子部件。您还可以查看您可以访问的对象的子对象。但是,如果给定的对象是无父对象,或者不属于小部件,那么您将不会以这种方式找到它。

于 2016-12-07T17:59:28.093 回答