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. QLineEdit::editingFinished called twice if press Enter key - actual bug?!
Forum Updated to NodeBB v4.3 + New Features

QLineEdit::editingFinished called twice if press Enter key - actual bug?!

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 4.1k Views 3 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #1

    Tested under Linux (Qt 5.9.5 released with Ubuntu 18.04), and reported to me by users under Windows (I have reason to believe they are running a later version of Qt, like 5.11+).

    1. Create a QLineEdit.
    2. Attach an editingFinished() slot.
    3. Make the slot put up some kind of dialog.
    4. Press the Return key in the line edit to finish your editing.

    You will get the dialog shown twice! :(

    Instead of Return, use, say, Tab key to finish editing. You will only get the dialog shown once.

    import sys
    from PyQt5 import QtWidgets
    
    
    def lineedit_editingFinished():
        mbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, "editingFinished called", "editingFinished called")
        mbox.exec()
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
    
        dlg = QtWidgets.QDialog()
        dlg.setFixedSize(400, 300)
        dlg.setLayout(QtWidgets.QVBoxLayout())
    
        lineedit = QtWidgets.QLineEdit()
        lineedit.editingFinished.connect(lineedit_editingFinished)
        dlg.layout().addWidget(lineedit)
    
        extraLineeditJustSoYouCanTabOutOfFirstOne = QtWidgets.QLineEdit()
        dlg.layout().addWidget(extraLineeditJustSoYouCanTabOutOfFirstOne)
    
        dlg.show()
    
        sys.exit(app.exec_())
    

    I don't think it's how/what you show as a dialog. But it needs something like that. It's something to do with the line edit losing focus to the up-popping dialog. But only when Return is pressed....

    If you don't open a window/dialog in the slot but just, say, send a message to console, you do not get the twice. If you don't show a dialog but instead place a breakpoint, you will end up with the twice. Again, something to do with the debugger swapping up-front windows, just like a dialog, causing it.

    Help/fix/workaround, please? :)

    sierdzioS 1 Reply Last reply
    0
    • JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #8

      The workaround is indeed:

          if (!lineEditorWidget->isModified())
              return; // Ignore second signal.
          lineEditorWidget->setModified(false);
          // Do something with the text. 
      

      i.e. you must clear the flag before doing something (which will invoke a dialog or similar) to prevent second, re-entrant call of editingFinished.

      1 Reply Last reply
      0
      • JonBJ JonB

        Tested under Linux (Qt 5.9.5 released with Ubuntu 18.04), and reported to me by users under Windows (I have reason to believe they are running a later version of Qt, like 5.11+).

        1. Create a QLineEdit.
        2. Attach an editingFinished() slot.
        3. Make the slot put up some kind of dialog.
        4. Press the Return key in the line edit to finish your editing.

        You will get the dialog shown twice! :(

        Instead of Return, use, say, Tab key to finish editing. You will only get the dialog shown once.

        import sys
        from PyQt5 import QtWidgets
        
        
        def lineedit_editingFinished():
            mbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, "editingFinished called", "editingFinished called")
            mbox.exec()
        
        
        if __name__ == '__main__':
            app = QtWidgets.QApplication(sys.argv)
        
            dlg = QtWidgets.QDialog()
            dlg.setFixedSize(400, 300)
            dlg.setLayout(QtWidgets.QVBoxLayout())
        
            lineedit = QtWidgets.QLineEdit()
            lineedit.editingFinished.connect(lineedit_editingFinished)
            dlg.layout().addWidget(lineedit)
        
            extraLineeditJustSoYouCanTabOutOfFirstOne = QtWidgets.QLineEdit()
            dlg.layout().addWidget(extraLineeditJustSoYouCanTabOutOfFirstOne)
        
            dlg.show()
        
            sys.exit(app.exec_())
        

        I don't think it's how/what you show as a dialog. But it needs something like that. It's something to do with the line edit losing focus to the up-popping dialog. But only when Return is pressed....

        If you don't open a window/dialog in the slot but just, say, send a message to console, you do not get the twice. If you don't show a dialog but instead place a breakpoint, you will end up with the twice. Again, something to do with the debugger swapping up-front windows, just like a dialog, causing it.

        Help/fix/workaround, please? :)

        sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #2

        @JonB said in QLineEdit::editingFinished called twice if press Enter key - actual bug?!:

        Help/fix/workaround, please? :)

        I've encountered the same thing today :-) SOunds like a bug to me, but I have not checked the bugtracker for it yet.

        A workaround (depending on your use case) is to use returnPressed() signal instead.

        (Z(:^

        JonBJ 1 Reply Last reply
        2
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by SGaist
          #3

          Hi,

          It might be QTBUG-40.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          JonBJ 1 Reply Last reply
          2
          • sierdzioS sierdzio

            @JonB said in QLineEdit::editingFinished called twice if press Enter key - actual bug?!:

            Help/fix/workaround, please? :)

            I've encountered the same thing today :-) SOunds like a bug to me, but I have not checked the bugtracker for it yet.

            A workaround (depending on your use case) is to use returnPressed() signal instead.

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

            @sierdzio
            Thanks for replying, useful to hear.

            A workaround (depending on your use case) is to use returnPressed() signal instead.

            It's deliberately editingFinished because the user might tab out, or click elsewhere, or.... Funnily enough, in the current case the user may well have used a QCompleter to populate the line edit and finish editing, so again he doesn't have to press Return. I just promised my stakeholders that these line edits would respond correctly to not pressing Return to finish editing!

            For now I've put in a "prevent-re-entrancy" flag on my editingFinished while the dialog is displayed to avoid bad behaviour, but I was hoping for a "nicer hack"? :)

            1 Reply Last reply
            0
            • SGaistS SGaist

              Hi,

              It might be QTBUG-40.

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

              @SGaist

              It might be QTBUG-40.

              Looks like similar wording. And look who's been assigned to fix it! :) But it's been there since 2010 (the 40th bug ever found), surely it would have been fixed by now? :)

              However, note my findings/example code --- in my case I am claiming this only happens if the Return key is pressed to cause the QLineEdit::editingFinished, I don't know if that's relevant or a special case? (Oh actually I think that's what the example in the 17 Jan '19 post says.)

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #6

                I've updated the link, it wasn't correctly accessible.

                The issue has been fixed for Qt 5.14.

                As for the assignment, look at the history ;-)

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                JonBJ 1 Reply Last reply
                1
                • SGaistS SGaist

                  I've updated the link, it wasn't correctly accessible.

                  The issue has been fixed for Qt 5.14.

                  As for the assignment, look at the history ;-)

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

                  @sgaist
                  Thank you! I have a couple of questions/observations:

                  • I see this bug was actually first reported in 2005. Is this 14-years-to-fix a record for a Qt bug? :)

                  • In the bug report link there is a workaround posted by a poster. I would like to implement this, as there is no chance of moving to a newer Qt version (I only use whatever Qt was released with the Linux version I use, so probably not until Ubuntu 20.04). It reads as follows:

                  I had to work around this bug once again today (Qt 5.6.1).
                  .
                  QLineEdit has a isModified interface. You can set this to true when editingFinished is emitted the first time and ignore the signal if and when it is emitted the second time.
                  .
                  You can also use this to ignore editingFinished if the text hasn't actually changed (i.e. the QLineEdit simply lost focus).
                  .
                  This is my slot/lambda:

                  connect(
                   lineEditorWidget,
                   &QLineEdit::editingFinished,
                   this,
                  [this, lineEditorWidget]()
                  { if (!lineEditorWidget->isModified()) return; // Ignore second signal. lineEditorWidget->setModified(false); // Do something with the text. } 
                  );
                  

                  Reading what he has written I am trying to confirm what his code really means to implement. Given the layout of his commented lines, do I presume this is intended to read as follows:

                  {
                      if (!lineEditorWidget->isModified())
                          return; // Ignore second signal.
                      // Do something with the text. 
                      lineEditorWidget->setModified(false);
                  }
                  

                  Thus we only setModified(false) after we have finished our slot code? If editingFinished is re-raised (by something) whilst we are inside the slot doing something with the text, we would execute our code again? As I typed this, I'm thinking he does genuinely mean

                      lineEditorWidget->setModified(false);
                      // Do something with the text. 
                  

                  which is different (you do the math): it ignores editingFinished being called a second time while inside the first editingFinished, it's a "only do this once per modification, regardless of when editingFinished is called"?

                  He also says:

                  You can set this to true when editingFinished is emitted the first time

                  but the code does not do that, does he mean the Qt framework is doing this, not us? https://doc.qt.io/qt-5/qlineedit.html#modified-prop :

                  The modified flag is never read by QLineEdit; it has a default value of false and is changed to true whenever the user changes the line edit's contents.

                  1 Reply Last reply
                  0
                  • JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #8

                    The workaround is indeed:

                        if (!lineEditorWidget->isModified())
                            return; // Ignore second signal.
                        lineEditorWidget->setModified(false);
                        // Do something with the text. 
                    

                    i.e. you must clear the flag before doing something (which will invoke a dialog or similar) to prevent second, re-entrant call of editingFinished.

                    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