Search code examples
pythonmodel-view-controllerpyqt5

PyQt5 Controller cannot access children names


for a python program I created a gui with QtDesigner. Inside my program the gui is initiated and calls the .ui-file to implement content. The gui class object is than given to a Controller, and here it gets tricky: Instead of one Controller, there are a main controller and some sub-controller for different parts of the gui. The main Controller does one or two general things and than hands over different parts of the gui to different sub controller. See the following example for better understanding:

import Controller             # import the folder with the controller

def __init__(self, window):
  self.window = window        # self.window is the handed over gui
  self.sub_controls()

def sub_controls(self):
  Controller.Sub_Controller_1(window = self.window.part_1)
  Controller.Sub_Controller_2(window = self.window.part_2)
  Controller.Sub_Controller_3(window = self.window.part_3)
   ...

The sub-Controller is set up like this:

def __init__(self, window):
  self.window = window
  ... # do stuff:

-----------------------------------------

by trying to call a widget in this Sub-Controller (lets say its a label called timmy), i get an error:

self.window.timmy.setVisible(False)

AttributeError: 'QWidget' object has no attribute 'timmy'

but by using the children()-Method, which returns a list of all children in the gui, I may access this label:

self.window.children()[1].setVisible(False)

This works well and hides timmy.

By trying to do this in the main Controller, it works fine as usual: self.window.timmy.setVisible(False) # works fine here

I also tried to save the sub-controller object like this:

def sub_controls(self):
  self.save_part_1 = Controller.Sub_Controller_1(window = self.window.part_1)

but this doesn't work.

Does any one have a suggestion, how I could solve this Problem? Sure, I couldt access just all widgets with the children()-method-list, but this is laborious because of the great amount of widgets. Same thing applies to reassigning every child.

PS: Unfortunately I cannot show you the original Code due to company guidelines.


Solution

  • Ok so I figured out, that the tree Structure of in each other nested widgets has nothing to do with the naming of the widgets. For example:

    MainWindow
      ->centralWidget
        ->otherWidget
          ->Button
    

    In this you can address "Button" with self.Button, because (how I believe) the name is saved in MainWindow-Level. If you cut out "otherWidget", the QPushButton in it still exists, but cannot addressed by name. So it's not possible to just hand over a part of your Gui to a Handler, at least if it's build with QtDesigner.

    My Solution for me to the original Problem is to hand over the complete Gui to every sub handler:

    def __init__(self, window):
      self.window = window        # self.window is the handed over gui
      self.sub_controls()
    
    def sub_controls(self):
      Controller.Sub_Controller_1(window = self.window)
      Controller.Sub_Controller_2(window = self.window)
      # Controller.Sub_Controller_3(window = self.window.part_3)      # before