Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PyQt 5: findChild returns None
Forum Updated to NodeBB v4.3 + New Features

PyQt 5: findChild returns None

Scheduled Pinned Locked Moved Solved Qt for Python
11 Posts 3 Posters 5.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Hubris
    wrote on last edited by
    #1

    Hi all,

    I have created a tabbed window where the labels and qlineedits are created using a for loop, distinguishing between the objects by having different objectName.

    class TabWidget(QWidget):
        def __init__(self, parent):
            super(QWidget, self).__init__(parent)
    
    item_names = [
                "so",
                "dc",
                "cn",
                "co",
                "ea",
                "tn",
                "sz",
                "m1",
                "m2",
                "ad",
                "de",
                "dl",
                "sd",
                "cp",
                "sh",
            ]
    
    for itemnum in range(0, len(item_names) - 2):
                self.label = QLabel(form_labels[itemnum])
                self.qledit = QLineEdit()
                if item_names[itemnum] == "so" or item_names[itemnum] == "dc":
                    self.qledit.setEnabled(False)
                self.label.setObjectName(f"{item_names[itemnum]}_l")
                self.qledit.setObjectName(f"{item_names[itemnum]}_qle")
                self.qledit.setFixedWidth(500)
                form_layout.addRow(self.label, self.qledit)
    
    

    This TabWidget class is then called in the setupUI function of the QMainWindow:

    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            print("Initialising UI...")
            self.tab_widget = TabWidget(self)
            print("UI initialised.")
            self.setCentralWidget(self.tab_widget)
            self.move(300, 150)
            self.setWindowTitle("TopperWorks DE Utility")
            self.show()
    

    I have omitted the layout formatting of the TabWidget as I believe that to be irrelevant to the question.
    I want to change the value of one of the qlineedits that I have created from the for loop with findChild:

    qle_by_name = self.findChild(QLineEdit, "dc_qle")
    qle_by_name.setText("Test")
    

    However, findChild returns None. The findChild usage is within the TabWidget class.

    Thanks.

    jsulmJ JonBJ 2 Replies Last reply
    0
    • H Hubris

      @JonB Once again thank you for the reply.

      I have done your suggestion and that indeed did suffice.

      I have considered @jsulm's reply. I used the following functions:

      ...
              print(self.findChildren(QWidget))
              print(self.findChildren(QLabel))
              print(self.findChildren(QLineEdit))
              print(self.findChildren(QPushButton))
              print(self.findChild(QLineEdit))
      ...
      

      which returned:

      []
      []
      []
      []
      None
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #8

      @Hubris
      OK, let's go back to basics :)

      You add your widgets via form_layout.addRow(self.label, self.qledit). Can you please

      • Show what form_layout is
      • Show how it is connected to your widget hierarchy, what its parent is

      We should like to try print(form_layout.findChildren()) to verify that can find the widgets you added. If form_layout is a layout (e.g. QFormLayout) then this needs to be called on its parent widget, e.g. form_layout.parentWidget().findChildren().

      Furthermore it is not clear when you are trying these findChild/findChildren() calls. They will only work when the layout/sub-widgets you have added have actually been added onto their parent to find from. For example, if you have added them to form_layout but that has not yet been set as the layout on a widget you won't find them.

      H 1 Reply Last reply
      2
      • H Hubris

        Hi all,

        I have created a tabbed window where the labels and qlineedits are created using a for loop, distinguishing between the objects by having different objectName.

        class TabWidget(QWidget):
            def __init__(self, parent):
                super(QWidget, self).__init__(parent)
        
        item_names = [
                    "so",
                    "dc",
                    "cn",
                    "co",
                    "ea",
                    "tn",
                    "sz",
                    "m1",
                    "m2",
                    "ad",
                    "de",
                    "dl",
                    "sd",
                    "cp",
                    "sh",
                ]
        
        for itemnum in range(0, len(item_names) - 2):
                    self.label = QLabel(form_labels[itemnum])
                    self.qledit = QLineEdit()
                    if item_names[itemnum] == "so" or item_names[itemnum] == "dc":
                        self.qledit.setEnabled(False)
                    self.label.setObjectName(f"{item_names[itemnum]}_l")
                    self.qledit.setObjectName(f"{item_names[itemnum]}_qle")
                    self.qledit.setFixedWidth(500)
                    form_layout.addRow(self.label, self.qledit)
        
        

        This TabWidget class is then called in the setupUI function of the QMainWindow:

        class MainWindow(QMainWindow):
            def __init__(self):
                super().__init__()
                self.initUI()
        
            def initUI(self):
                print("Initialising UI...")
                self.tab_widget = TabWidget(self)
                print("UI initialised.")
                self.setCentralWidget(self.tab_widget)
                self.move(300, 150)
                self.setWindowTitle("TopperWorks DE Utility")
                self.show()
        

        I have omitted the layout formatting of the TabWidget as I believe that to be irrelevant to the question.
        I want to change the value of one of the qlineedits that I have created from the for loop with findChild:

        qle_by_name = self.findChild(QLineEdit, "dc_qle")
        qle_by_name.setText("Test")
        

        However, findChild returns None. The findChild usage is within the TabWidget class.

        Thanks.

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @Hubris You could iterate over all children (https://doc.qt.io/qt-6/qobject.html#children) and print out their names to see whether you really have such an object.
        As far as I can see you also never set the parent on the labels and line edits.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        H 1 Reply Last reply
        1
        • H Hubris

          Hi all,

          I have created a tabbed window where the labels and qlineedits are created using a for loop, distinguishing between the objects by having different objectName.

          class TabWidget(QWidget):
              def __init__(self, parent):
                  super(QWidget, self).__init__(parent)
          
          item_names = [
                      "so",
                      "dc",
                      "cn",
                      "co",
                      "ea",
                      "tn",
                      "sz",
                      "m1",
                      "m2",
                      "ad",
                      "de",
                      "dl",
                      "sd",
                      "cp",
                      "sh",
                  ]
          
          for itemnum in range(0, len(item_names) - 2):
                      self.label = QLabel(form_labels[itemnum])
                      self.qledit = QLineEdit()
                      if item_names[itemnum] == "so" or item_names[itemnum] == "dc":
                          self.qledit.setEnabled(False)
                      self.label.setObjectName(f"{item_names[itemnum]}_l")
                      self.qledit.setObjectName(f"{item_names[itemnum]}_qle")
                      self.qledit.setFixedWidth(500)
                      form_layout.addRow(self.label, self.qledit)
          
          

          This TabWidget class is then called in the setupUI function of the QMainWindow:

          class MainWindow(QMainWindow):
              def __init__(self):
                  super().__init__()
                  self.initUI()
          
              def initUI(self):
                  print("Initialising UI...")
                  self.tab_widget = TabWidget(self)
                  print("UI initialised.")
                  self.setCentralWidget(self.tab_widget)
                  self.move(300, 150)
                  self.setWindowTitle("TopperWorks DE Utility")
                  self.show()
          

          I have omitted the layout formatting of the TabWidget as I believe that to be irrelevant to the question.
          I want to change the value of one of the qlineedits that I have created from the for loop with findChild:

          qle_by_name = self.findChild(QLineEdit, "dc_qle")
          qle_by_name.setText("Test")
          

          However, findChild returns None. The findChild usage is within the TabWidget class.

          Thanks.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #3

          @Hubris
          In addition/follow up to @jsulm

          form_layout.addRow(self.label, self.qledit)

          As code stands form_layout is a non-existent local variable.

          Separate issue:

                      self.label = QLabel(form_labels[itemnum])
                      self.qledit = QLineEdit()
          

          You are executing these statements multiple times inside a loop. These should not be assigned to (the same) class member variables.

          H 1 Reply Last reply
          0
          • jsulmJ jsulm

            @Hubris You could iterate over all children (https://doc.qt.io/qt-6/qobject.html#children) and print out their names to see whether you really have such an object.
            As far as I can see you also never set the parent on the labels and line edits.

            H Offline
            H Offline
            Hubris
            wrote on last edited by
            #4

            @jsulm Thanks for the reply. I used self.findChildren to return the QLineEdit, QPushbutton, and QLabel children but it just returns an empty array.

            I also tried to set the parent for the objects by using self.qledit.setParent(TabWidget), however I encounter the following error:

            setParent(self, QWidget): argument 1 has unexpected type 'sip.wrappertype'
            
            1 Reply Last reply
            0
            • JonBJ JonB

              @Hubris
              In addition/follow up to @jsulm

              form_layout.addRow(self.label, self.qledit)

              As code stands form_layout is a non-existent local variable.

              Separate issue:

                          self.label = QLabel(form_labels[itemnum])
                          self.qledit = QLineEdit()
              

              You are executing these statements multiple times inside a loop. These should not be assigned to (the same) class member variables.

              H Offline
              H Offline
              Hubris
              wrote on last edited by
              #5

              @JonB Thanks for the reply.

              form_layout is declared as a QFormLayout object earlier in the code. I just omitted that section. If you'd need that information I am happy to provide the whole code.

              As for assigning to the same class member variables inside the for loop,

              I am making a form which has a lot of multiple repeating QLabels, and QLineEdits. If I do not instantiate a new label for every loop, I would just be modifying the same QLabel/QLineEdit every iteration, and the result of that is undesirable.

              Is this idea not the right approach?

              Here is the output of my code:
              1134a16e-6cc7-46e2-a7cc-26e9e6f65b64-image.png

              Each QLabel and QLineEdit has a distinct objectName.

              JonBJ 1 Reply Last reply
              0
              • H Hubris

                @JonB Thanks for the reply.

                form_layout is declared as a QFormLayout object earlier in the code. I just omitted that section. If you'd need that information I am happy to provide the whole code.

                As for assigning to the same class member variables inside the for loop,

                I am making a form which has a lot of multiple repeating QLabels, and QLineEdits. If I do not instantiate a new label for every loop, I would just be modifying the same QLabel/QLineEdit every iteration, and the result of that is undesirable.

                Is this idea not the right approach?

                Here is the output of my code:
                1134a16e-6cc7-46e2-a7cc-26e9e6f65b64-image.png

                Each QLabel and QLineEdit has a distinct objectName.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #6

                @Hubris
                That's fine.

                The observation about your class variables is probably not relevant. They end up referencing just the final label/edit you happen to create from the loop. I doubt that is useful to you as a member variable reference.

                            label = QLabel(form_labels[itemnum])
                            qledit = QLineEdit()
                            ...
                

                Wouldn't this suffice?

                If I wanted to debug your situation I'd start with @jsulm's

                @Hubris You could iterate over all children (https://doc.qt.io/qt-6/qobject.html#children) and print out their names to see whether you really have such an object.

                You could also do a quick self.findChild(QLineEdit) to see whether it finds any line edits.

                H 1 Reply Last reply
                0
                • JonBJ JonB

                  @Hubris
                  That's fine.

                  The observation about your class variables is probably not relevant. They end up referencing just the final label/edit you happen to create from the loop. I doubt that is useful to you as a member variable reference.

                              label = QLabel(form_labels[itemnum])
                              qledit = QLineEdit()
                              ...
                  

                  Wouldn't this suffice?

                  If I wanted to debug your situation I'd start with @jsulm's

                  @Hubris You could iterate over all children (https://doc.qt.io/qt-6/qobject.html#children) and print out their names to see whether you really have such an object.

                  You could also do a quick self.findChild(QLineEdit) to see whether it finds any line edits.

                  H Offline
                  H Offline
                  Hubris
                  wrote on last edited by
                  #7

                  @JonB Once again thank you for the reply.

                  I have done your suggestion and that indeed did suffice.

                  I have considered @jsulm's reply. I used the following functions:

                  ...
                          print(self.findChildren(QWidget))
                          print(self.findChildren(QLabel))
                          print(self.findChildren(QLineEdit))
                          print(self.findChildren(QPushButton))
                          print(self.findChild(QLineEdit))
                  ...
                  

                  which returned:

                  []
                  []
                  []
                  []
                  None
                  
                  JonBJ 1 Reply Last reply
                  0
                  • H Hubris

                    @JonB Once again thank you for the reply.

                    I have done your suggestion and that indeed did suffice.

                    I have considered @jsulm's reply. I used the following functions:

                    ...
                            print(self.findChildren(QWidget))
                            print(self.findChildren(QLabel))
                            print(self.findChildren(QLineEdit))
                            print(self.findChildren(QPushButton))
                            print(self.findChild(QLineEdit))
                    ...
                    

                    which returned:

                    []
                    []
                    []
                    []
                    None
                    
                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #8

                    @Hubris
                    OK, let's go back to basics :)

                    You add your widgets via form_layout.addRow(self.label, self.qledit). Can you please

                    • Show what form_layout is
                    • Show how it is connected to your widget hierarchy, what its parent is

                    We should like to try print(form_layout.findChildren()) to verify that can find the widgets you added. If form_layout is a layout (e.g. QFormLayout) then this needs to be called on its parent widget, e.g. form_layout.parentWidget().findChildren().

                    Furthermore it is not clear when you are trying these findChild/findChildren() calls. They will only work when the layout/sub-widgets you have added have actually been added onto their parent to find from. For example, if you have added them to form_layout but that has not yet been set as the layout on a widget you won't find them.

                    H 1 Reply Last reply
                    2
                    • JonBJ JonB

                      @Hubris
                      OK, let's go back to basics :)

                      You add your widgets via form_layout.addRow(self.label, self.qledit). Can you please

                      • Show what form_layout is
                      • Show how it is connected to your widget hierarchy, what its parent is

                      We should like to try print(form_layout.findChildren()) to verify that can find the widgets you added. If form_layout is a layout (e.g. QFormLayout) then this needs to be called on its parent widget, e.g. form_layout.parentWidget().findChildren().

                      Furthermore it is not clear when you are trying these findChild/findChildren() calls. They will only work when the layout/sub-widgets you have added have actually been added onto their parent to find from. For example, if you have added them to form_layout but that has not yet been set as the layout on a widget you won't find them.

                      H Offline
                      H Offline
                      Hubris
                      wrote on last edited by
                      #9

                      @JonB Wow. You hit the nail on the head.

                      As it turned out I was using tabs in my GUI, where each tab was its own QWidget. The parent for the objects was that QWidget.

                      Many thanks. I have learned something new today. I still need to read up a bit more on Children and Parents to fully understand it.

                      1 Reply Last reply
                      1
                      • H Offline
                        H Offline
                        Hubris
                        wrote on last edited by Hubris
                        #10

                        Here is the code snippet that best explains that:

                                form_layout = QFormLayout()
                        
                                # Array of
                                form_labels = [
                                    "Sales Order #",
                                    "Date Created",
                                    "Customer Name",
                                    "Contact #",
                                    "Email Address",
                                    "Template Name",
                                    "Size",
                                    "Material 1",
                                    "Material 2",
                                    "Additional",
                                    "Delivery",
                                    "Delivery Location",
                                    "Ship by Date",
                                    "Completed",
                                    "Shipped",
                                ]
                        
                                item_names = [
                                    "so",
                                    "dc",
                                    "cn",
                                    "co",
                                    "ea",
                                    "tn",
                                    "sz",
                                    "m1",
                                    "m2",
                                    "ad",
                                    "de",
                                    "dl",
                                    "sd",
                                    "cp",
                                    "sh",
                                ]
                        
                                # ---------- Create new tab ----------#
                                tabs = QTabWidget()
                                new_tab = QWidget()
                        
                                for itemnum in range(0, len(item_names) - 2):
                                    label = QLabel(form_labels[itemnum])
                                    qledit = QLineEdit()
                                    if item_names[itemnum] == "so" or item_names[itemnum] == "dc":
                                        qledit.setEnabled(False)
                                    label.setText(form_labels[itemnum])
                                    label.setObjectName(f"{item_names[itemnum]}_l")
                                    qledit.setObjectName(f"{item_names[itemnum]}_qle")
                                    # self.qledit.setParent(TabWidget)
                                    qledit.setFixedWidth(500)
                                    form_layout.addRow(label, qledit)
                        
                                cl_btn = QPushButton("Clear Fields")
                                ce_btn = QPushButton("Create Entry")
                                em_l = QLabel()
                        
                                btn_box = QHBoxLayout()
                                btn_box.addWidget(em_l)
                                btn_box.addWidget(ce_btn)
                                btn_box.addWidget(cl_btn)
                        
                                form_layout.addRow(btn_box)
                                new_tab.setLayout(form_layout)
                        
                                qle_by_name = new_tab.findChild(QLineEdit, "dc_qle")
                                qle_by_name.setText("Test")
                        
                        JonBJ 1 Reply Last reply
                        0
                        • H Hubris

                          Here is the code snippet that best explains that:

                                  form_layout = QFormLayout()
                          
                                  # Array of
                                  form_labels = [
                                      "Sales Order #",
                                      "Date Created",
                                      "Customer Name",
                                      "Contact #",
                                      "Email Address",
                                      "Template Name",
                                      "Size",
                                      "Material 1",
                                      "Material 2",
                                      "Additional",
                                      "Delivery",
                                      "Delivery Location",
                                      "Ship by Date",
                                      "Completed",
                                      "Shipped",
                                  ]
                          
                                  item_names = [
                                      "so",
                                      "dc",
                                      "cn",
                                      "co",
                                      "ea",
                                      "tn",
                                      "sz",
                                      "m1",
                                      "m2",
                                      "ad",
                                      "de",
                                      "dl",
                                      "sd",
                                      "cp",
                                      "sh",
                                  ]
                          
                                  # ---------- Create new tab ----------#
                                  tabs = QTabWidget()
                                  new_tab = QWidget()
                          
                                  for itemnum in range(0, len(item_names) - 2):
                                      label = QLabel(form_labels[itemnum])
                                      qledit = QLineEdit()
                                      if item_names[itemnum] == "so" or item_names[itemnum] == "dc":
                                          qledit.setEnabled(False)
                                      label.setText(form_labels[itemnum])
                                      label.setObjectName(f"{item_names[itemnum]}_l")
                                      qledit.setObjectName(f"{item_names[itemnum]}_qle")
                                      # self.qledit.setParent(TabWidget)
                                      qledit.setFixedWidth(500)
                                      form_layout.addRow(label, qledit)
                          
                                  cl_btn = QPushButton("Clear Fields")
                                  ce_btn = QPushButton("Create Entry")
                                  em_l = QLabel()
                          
                                  btn_box = QHBoxLayout()
                                  btn_box.addWidget(em_l)
                                  btn_box.addWidget(ce_btn)
                                  btn_box.addWidget(cl_btn)
                          
                                  form_layout.addRow(btn_box)
                                  new_tab.setLayout(form_layout)
                          
                                  qle_by_name = new_tab.findChild(QLineEdit, "dc_qle")
                                  qle_by_name.setText("Test")
                          
                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by
                          #11

                          @Hubris said in PyQt 5: findChild returns None:

                              new_tab.setLayout(form_layout)
                          
                              qle_by_name = new_tab.findChild(QLineEdit, "dc_qle")
                          

                          Yes, this makes sense for finding the child widgets! :)

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved