findChild on object created within pyqt designer

2020-07-23 03:22发布

I have the following problem with my pyqt:

Assuming i create an object within the Qt Designer and save it as an .ui file. Then i use pyuic to convert it to an .py file. Because i want to integrate a new module into a given program, this is the favorite way to go (because later the .ui files will be converted automatically at startup to .py files).

If i have a look at my .py file i see the following for the window:

class Ui_SubWindow(object):
    def setupUi(self, SubWindow):
        SubWindow.setObjectName(_fromUtf8("SubWindow"))
        ....

i have a RemoteWindow class as MainWindow where the SubWindow is initiated:

class RemoteWindow(QtGui.QMainWindow):
  def __init__(self, subcore):
    super(RemoteWindow, self).__init__(subcore.core.gui)
    self.subcore = subcore
    self.ui = Ui_SubWindow()

Now i have a core program:

class SubCore(object):
  def __init__(self, core, identity, number):
    ...
    self.gui = RemoteWindow(self)
    self.newController = NewController(self.gui)

and the new controller class:

class NewController(object):
  def __init__(self, subwindow):
    self.subwindow = subwindow
    self.ui = subwindow.ui

from my controller i want to call a .findChild() on that window

submitFrame = self.ui.findChild(QtGui.QFrame, "frameSubmit")

, but all i get is an:

AttributeError: 'Ui_SubWindow' object has no attribute 'findChild'

I assume this is, because the class Ui_SubWindow is not a child class of some QObject but of an object, am i right?

self.ui is the same as subwindow.ui, where subwindow is an instance of RemoteWindow which has as .ui argument the Ui_SubWindow Class.

Is there any chance to make the pyuic or the Qt Designer to make this SubWindow a child of QObject, without manipulating the automatically generated .py file?

3条回答
聊天终结者
2楼-- · 2020-07-23 04:05

Qt Designer creates a design, that is, a class that serves to fill the main widget so the internal widgets are not children of this class, if you want to use findChild you must do it to the widget that returns this class after calling the method setupUi.

class RemoteWindow(QtGui.QMainWindow):
  def __init__(self, subcore):
    super(RemoteWindow, self).__init__(subcore.core.gui)
    self.subcore = subcore
    self.ui = Ui_SubWindow()
    self.ui.setupUi(self) # Here the widget is filled
    [...]

And then you should use it in the following way:

class NewController(object):
  def __init__(self, subwindow):
    self.subwindow = subwindow
    submitFrame = self.subwindow.findChild(QtGui.QFrame, "frameSubmit")
    [...]
查看更多
ゆ 、 Hurt°
3楼-- · 2020-07-23 04:12

I recently had to do this same thing and leaving this here in case someone sees this link vs the other related one. https://stackoverflow.com/a/62340205/1621381

for name, obj in dict(self.__dict__).items():
        # print(str(name) + str(obj))
        obj_type = str(obj).strip("<PyQt5").rsplit(" ")[0].replace(".", '', 1)
        # obj_type = str(obj).strip("<").rsplit(" ")[0]
        # print(obj_type)
        # obj_type = obj_str.strip("<PyQt5").rsplit(" ")[0].replace(".", '', 1)
        label_name = "self." + str(name)
        try:
            label_name = self.findChild(eval(obj_type), name)
            print(str(label_name) + ' created')
        except:
            pass
        if not isinstance(obj_type, QObject):
            continue
查看更多
Deceive 欺骗
4楼-- · 2020-07-23 04:18

You don't need to use findChild at all, because pyuic will automatically create attributes in the ui object for all the widgets defined in Qt Designer. The attribute names are taken from the objectName. So all you need is:

submitFrame = self.ui.frameSubmit
查看更多
登录 后发表回答