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. Reset the editor of a QTableWidget instead of entering it when the editor loses focus
Forum Updated to NodeBB v4.3 + New Features

Reset the editor of a QTableWidget instead of entering it when the editor loses focus

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

    Hi :-)

    I have a QTableWidgetItem I use a QStyledItemDelegate on (mostly because I needed a custom setModelData function).

    I would like to change the default behavior of editing, which is: The editing is finished if the user presses Enter, Return or the editor loses focus (which seems to be the default for a QLineEdit, according to the docs. At least, in this case, the editingFinished signal is emitted). I don't want the data to be comitted on focus loss, only on Enter/Return pressing.

    So I created my own QLineEdit derived editor and implemented a custom createEditor function in the delegate, using this one.

    Ifirst tried to reimplement the editor's focusOutEvent, where I set the entered text back to the initial value before passing the event to the base class. Problem is that setModelData is called before the focusOutEvent function.

    I then tried to reimplement the whole event function and looked for something to happen earlier. The first thing I found was event->type() to be QEvent::aboutToChangeFocus, but even with this one, setModelData is called earlier.

    I also tried to figure out how the editor is connected to the delegate and at which very point setModelData is invoked. But I didn't find it (those Qt sources are quite complicated sometimes :-( at least for a hobby programmer like I am).

    So is there any way to change this? One can break this down into the question: How can I know if the editor was closed via pressing Enter/Return or via focus loss?

    Thanks for all help!

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Set a breakpoint in setModelData() and take a look at the backtrace to see from where it is called.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      l3u_L 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        Set a breakpoint in setModelData() and take a look at the backtrace to see from where it is called.

        l3u_L Offline
        l3u_L Offline
        l3u_
        wrote on last edited by
        #3

        @Christian-Ehrlicher I'm not sure I'm fit enough with this stuff but I tried it ;-)

        Apparently, setModelData is called via QAbstractItemDelegate::commitData(QWidget*), but I still don't know how it works …

        Question is if I need to know how the internals work, as I only want to handle the editingFinished signal (I suppose) and decide, based on if Enter/Return has been pressed or the focus was lost, if I reset or commit the data …

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @l3u_ said in Reset the editor of a QTableWidget instead of entering it when the editor loses focus:

          but I still don't know how it works …

          You should not know how it works you should take a look at the backtrace to see from where it is triggered - somewhere the text must be read from the QLineEdit which is nearby the place you can jump in.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          l3u_L 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @l3u_ said in Reset the editor of a QTableWidget instead of entering it when the editor loses focus:

            but I still don't know how it works …

            You should not know how it works you should take a look at the backtrace to see from where it is triggered - somewhere the text must be read from the QLineEdit which is nearby the place you can jump in.

            l3u_L Offline
            l3u_L Offline
            l3u_
            wrote on last edited by l3u_
            #5

            @Christian-Ehrlicher Apparently, I just can't read it?!

            #0  0x00005555556783de in PlayersPageDelegate::setModelData(QWidget*, QAbstractItemModel*, QModelIndex const&) const ()
            #1  0x00007ffff7a8f325 in QAbstractItemView::commitData(QWidget*) ()
            from /usr/lib64/libQt5Widgets.so.5
            #2  0x00007ffff7a8e480 in ?? () from /usr/lib64/libQt5Widgets.so.5
            #3  0x00007ffff6f5daae in QMetaObject::activate(QObject*, int, int, void**) ()
            from /usr/lib64/libQt5Core.so.5
            #4  0x00007ffff7aa8adf in QAbstractItemDelegate::commitData(QWidget*) ()
            from /usr/lib64/libQt5Widgets.so.5
            #5  0x00007ffff7aa9845 in ?? () from /usr/lib64/libQt5Widgets.so.5
            #6  0x00007ffff7aa99a8 in ?? () from /usr/lib64/libQt5Widgets.so.5
            #7  0x00007ffff6f5e66a in QObject::event(QEvent*) () from /usr/lib64/libQt5Core.so.5
            #8  0x00007ffff7841501 in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
            from /usr/lib64/libQt5Widgets.so.5
            #9  0x00007ffff7848af8 in QApplication::notify(QObject*, QEvent*) ()
            from /usr/lib64/libQt5Widgets.so.5
            #10 0x00007ffff6f358a1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
            from /usr/lib64/libQt5Core.so.5
            #11 0x00007ffff6f389c6 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
            from /usr/lib64/libQt5Core.so.5
            #12 0x00007ffff6f86763 in ?? () from /usr/lib64/libQt5Core.so.5
            #13 0x00007ffff5b046fd in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
            #14 0x00007ffff5b04998 in ?? () from /usr/lib64/libglib-2.0.so.0
            #15 0x00007ffff5b04a2c in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
            #16 0x00007ffff6f86503 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
                () from /usr/lib64/libQt5Core.so.5
            #17 0x00007ffff6f34873 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
            from /usr/lib64/libQt5Core.so.5
            #18 0x00007ffff6f3c482 in QCoreApplication::exec() () from /usr/lib64/libQt5Core.so.5
            #19 0x00005555556034c6 in main ()
            

            Seems like it's called by QAbstractItemDelegate::commitData, but I can't override it in my delegate ("… is marked as override but doesn't")? [Edit:] Okay, that's because it's a signal, not a function.

            1 Reply Last reply
            0
            • Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Seems like I still don't understand what you want to achieve - you don't want to commit the data when the focus changes, or why do you try to fiddle around with the focus event?
              You want to commit the data when enter is pressed - then you have to watch for Qt::KeyEnter in the QLineEdit::keyPressEvent() and then emit QAbstractItemDelegate::commitData() - this is what's done for the focusOut/ChangeEvent as you can see in the backtrace.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              l3u_L 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                Seems like I still don't understand what you want to achieve - you don't want to commit the data when the focus changes, or why do you try to fiddle around with the focus event?
                You want to commit the data when enter is pressed - then you have to watch for Qt::KeyEnter in the QLineEdit::keyPressEvent() and then emit QAbstractItemDelegate::commitData() - this is what's done for the focusOut/ChangeEvent as you can see in the backtrace.

                l3u_L Offline
                l3u_L Offline
                l3u_
                wrote on last edited by l3u_
                #7

                @Christian-Ehrlicher If Enter/Return is pressed in the editor, the data should be comitted. Just as it's the case now. But if the editor loses focus, nothing should happen, the editing should be aborted. Per default, if I click somewhere outside the editor (after having changed something), it's the same as if I pressed Enter/Return.

                The problem is that I don't know what to change to achieve this and where to change it (in a custom editor or the delegate) … also, I don't know at which point which signals from the editor are connected to the delegate.

                What I don't understand is: If the focusOutEvent causes editingFinshed to be emitted which finally causes commitData to be emitted and setModelData to be called, then why is setModelData called before I see focusOutEvent being called?!

                1 Reply Last reply
                0
                • l3u_L Offline
                  l3u_L Offline
                  l3u_
                  wrote on last edited by l3u_
                  #8

                  Okay. I worked around it. I implemented a custom QLineEdit used by the delegate with:

                  void PlayersEditor::keyPressEvent(QKeyEvent *event)
                  {
                      if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
                          m_enterPressed = true;
                      }
                      QLineEdit::keyPressEvent(event);
                  }
                  

                  and

                  bool PlayersEditor::enterPressed() const
                  {
                      return m_enterPressed;
                  }
                  

                  And in my QStyledItemDelegate's setModelData, I simply do

                  if (! m_editor->enterPressed()) {
                      return;
                  }
                  

                  Which leaves the model unchanged and "just" closes the editor. Maybe not the "right" way, but it works …

                  Edit: Just to mention this: one has to declare m_editor as mutable to be able tol set it inside createEditor, as this function is const.

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

                    Hi,

                    Out of curiosity, why do you want that behavior ?

                    It's kind of counter intuitive with regard to how applications work with that kind of editing feature.

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

                    l3u_L 1 Reply Last reply
                    1
                    • SGaistS SGaist

                      Hi,

                      Out of curiosity, why do you want that behavior ?

                      It's kind of counter intuitive with regard to how applications work with that kind of editing feature.

                      l3u_L Offline
                      l3u_L Offline
                      l3u_
                      wrote on last edited by l3u_
                      #10

                      @SGaist The table widget I use is not intended to be used like a spread sheet (LibreOffice or Excel). It's a list of names with additional columns one can trigger actions on. And normally, one doesn't edit the name, as long as one doesn't see a typo or such in it.

                      So clicking outside the edited name item is either a mistake or a "oh, I wanted to do something else before". So I think, for my use-case, it's better to have the user to confirm an edit action by pressing Enter or Return rather than clicking somewhere outside the editor.

                      Maybe a corner-case ;-)

                      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