Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Removed QLineEdit gets focus. Is this a bug?



  • 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.


  • Lifetime Qt Champion

    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.



  • 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.



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


  • Lifetime Qt Champion

    @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. :)


Log in to reply