Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Removed QLineEdit gets focus. Is this a bug?
Qt 6.11 is out! See what's new in the release blog

Removed QLineEdit gets focus. Is this a bug?

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 1.2k Views 1 Watching
  • 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.
  • I Offline
    I Offline
    isar
    wrote on last edited by isar
    #1

    I'll illustrate the problem with Qt for Python for the sake of simple setup. Exactly the same problem appears with Qt/C++.

    import sys
    from PySide2.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout, QFormLayout, QLineEdit, QGroupBox, QMessageBox, QWidget, QPushButton
    
    class MyWidget(QWidget):
        def __init__(self):
            super().__init__()
    
            #HLayout
            # Button->remove&hide(Widget1)
            # GroupBox(&G), VLayout
            #  Widget1, FormLayout
            #   LineEdit
            #  Widget2, FormLayout
            #   LineEdit
    
            layout = QHBoxLayout(self)
    
            group_box = QGroupBox("&Group", self)
            group_layout = QVBoxLayout(group_box)
    
            widget1 = QWidget(self)
            form_layout1 = QFormLayout(widget1)
            line_edit = QLineEdit(widget1)
            line_edit.textEdited.connect(lambda: QMessageBox.information(self, "info", "typed"))
            form_layout1.addWidget(line_edit)
            group_layout.addWidget(widget1)
    
            widget2 = QWidget(self)
            form_layout1 = QFormLayout(widget2)
            line_edit = QLineEdit(widget2)
            form_layout1.addWidget(line_edit)
            group_layout.addWidget(widget2)
    
            layout.addWidget(group_box)
    
            button = QPushButton("button", self)
            button.clicked.connect(lambda: (group_layout.removeWidget(widget1), widget1.hide()))
            layout.addWidget(button)
    
    
    if __name__ == "__main__":
        app = QApplication([])
        window = MyWidget()
        window.show()
        sys.exit(app.exec_())
    

    Steps to reproduce the problem: run the program, click the button, press "Alt+G", press"a". A window unexpectedly pops up.

    The structure of the UI is basically:

    • QWidget with QHBoxLayout
      • QGroupBox("&G") with QVBoxLayout
        • widget1 = QWidget, FormLayout
          - QLineEdit, textChanged.connect(popup)
        • widget2 = QWidget, FormLayout
          - QLineEdit
      • QPushButton, clicked.connect(remove(widget1); widget1.hide())

    Initially, the QLineEdit of widget1 gets the focus. By clicking the button, widget1 gets hidden and removed from its parent's layout. Next, by pressing "Alt+G", the QGroupBox gets the focus (and is supposed to pass it on to the second QLineEdit). Finally, by pressing 'a', a QMessageBox pops up, which means that it is in fact the first QLineEdit, which has been removed along with its parent widget1 from the QGroupBox, who gets the focus.

    Could anyone explain this behavior? Thanks.

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi and welcome to the forums.

      Could not test your code as not python user but i could reproduce it
      in c++ with a similar setup.

      The reason is that removeWidget does NOTHING but remove it from the layout and it still has
      the same parent/ownership and such. So it seems that GroupBox somehow not aware it was hidden
      so it still has it in tabOrder list.

      Anyhow, in c++ it works correctly if i ask layout to update() after removing the widget.

      I assume something like
      button.clicked.connect(lambda: (group_layout.removeWidget(widget1),group_layout.update(), widget1.hide()))

      Then it correctly gives focus to the remaining visible linedit in widget2 and not the hidden one
      when i press alt+G to focus GrpBox.

      I 1 Reply Last reply
      2
      • I Offline
        I Offline
        isar
        wrote on last edited by isar
        #3

        Many thanks for your help.
        Unfortunately group_layout.update() does not change the behavior on my side. Could you please paste a complete running example in c++/python with the fixed behavior, where "press button -> Alt+G -> press 'a'" gives no message box? Note that no TAB is supposed to be pressed during the process, since even without group_layout.update(), it's easy to see by pressing TAB a few times that the removed line_edit of widget1 is already out of the tab order, but that does not justify the problem.

        1 Reply Last reply
        0
        • mrjjM mrjj

          Hi and welcome to the forums.

          Could not test your code as not python user but i could reproduce it
          in c++ with a similar setup.

          The reason is that removeWidget does NOTHING but remove it from the layout and it still has
          the same parent/ownership and such. So it seems that GroupBox somehow not aware it was hidden
          so it still has it in tabOrder list.

          Anyhow, in c++ it works correctly if i ask layout to update() after removing the widget.

          I assume something like
          button.clicked.connect(lambda: (group_layout.removeWidget(widget1),group_layout.update(), widget1.hide()))

          Then it correctly gives focus to the remaining visible linedit in widget2 and not the hidden one
          when i press alt+G to focus GrpBox.

          I Offline
          I Offline
          isar
          wrote on last edited by
          #4

          @mrjj ok it seems that widget1.setParent(nullptr) is the solution and it implies a removal from the layout.

          mrjjM 1 Reply Last reply
          0
          • I isar

            @mrjj ok it seems that widget1.setParent(nullptr) is the solution and it implies a removal from the layout.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @isar
            yes i also tried that but thought it was a bit overkill.
            Apparently update() is not enough always. My test was actually made in Designer and i just use textChange signal to see where i typed and it was easy to get same effect that
            setting focus back to Group after i hide widget1 would still focus the hidden line edit and type to it.

            So for me, it smells as a bug as hidden widgets should not get keyboard focus.
            And the GroupBox clearly set focus to a hidden lineedit. :)

            1 Reply Last reply
            0

            • Login

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