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. QTableView on editing last row add new line
QtWS25 Last Chance

QTableView on editing last row add new line

Scheduled Pinned Locked Moved Solved General and Desktop
qtableviewblank row
6 Posts 3 Posters 3.6k 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.
  • R Offline
    R Offline
    Rhdr
    wrote on last edited by Rhdr
    #1

    I am redoing a legacy system built in ms access and want to simulate the same behavior when adding records to tables. In Access when adding records to a table, access automatically adds a new blank row to the bottom of the record set. I have a custom model with an insertBlankRow function (it calls beginInsertRows() & endInsertRows()), but I need a signal to correctly time the insertion

    Option A:
    I tried sub-classing a delegate/editor and emitted a signal from createEditor(), but when I add the blank row whilst the editor is open the editor's position is not updated correctly. How can I update the editors position to take into account the newly inserted row?

    Option B:
    If I can emit a signal just before an editor is created, then I could add the blank record. How/Where would you emit a signal just before a editor on a QTableview is to be opened?

    PS: Its a PyQt5 app but please feel free to share ideas in either C++ or PyQt (or links)

    EDIT: Sorry I should have mentioned that I have opened up persistent editors/delegates for combo-boxes on certain columns and these editors' alignment are giving me trouble when inserting new rows.

    1 Reply Last reply
    0
    • JonBJ JonB

      @Rhdr
      If I understand right, you need an "edit signal" before CreateEditor() is called, right?

      So since I too do not see any signal for this, look at your QTableView's editTriggers (https://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop) and implement your own slot(s) on the event(s)/signal(s) which are going to going to take you into edit mode?

      Another possibility is QTableView::edit() slot (https://doc.qt.io/qt-5/qabstractitemview.html#edit)

      Starts editing the item corresponding to the given index if it is editable.

      Does that get called before the CreateEditor()? In which case that might be the signal you were looking for?

      Actually it's not terribly clear to me how/when you do this "extra blank row for adding a row". If you do not always have a blank row there won't be anything for the user to edit, so they must have to click a button? If you do have a blank row sitting there all the time, then the signal you are looking for when to add a new blank line is something about after the user has edited the blank line, for next time around. I leave that to you.

      R Offline
      R Offline
      Rhdr
      wrote on last edited by Rhdr
      #4

      @JonB thanks for the reply. Similar to MS Access I have a blank row at the bottom at all times, if the user edit it a new blank row appear below it.

      I got it working by:

      1. Overwriting the delegate and emitting a signal from createEditor(),
      2. then inserted the blank record,
      3. then calling scheduleDelayedItemsLayout() on the QTableView to re-allign the editors.
        (My custom model mange the amount of blank records that can be added this way)
        (Also you just need to disconnect & reconnect the signal when opening persistent editors)

      Edit: I still ran into a bunch of quirks,,, however there is a much simpler way to achieve more or less the same effect. Create 2 TableViews and use the bottom one as the "add new record" table. Link both table's QHeaderViews to make sure their columns stay in sync!

      Edit2: Be sure to see VRonin's answer below for a link to a working C++ model that does exactly what the original question asked

      1 Reply Last reply
      0
      • R Offline
        R Offline
        Rhdr
        wrote on last edited by Rhdr
        #2

        Found part of the solution: After adding the new blank row you can loop through the QTableView, remove and then re-open the persistent editors. This will re-align their positions correctly, however the operation is costly.

        I am not sure other than removing persistence altogether if there would be a better way? (Edit: If you call scheduleDelayedItemsLayout() https://doc.qt.io/qt-5/qabstractitemview.html#scheduleDelayedItemsLayout then the editors is updated correctly no need for recreating)

        Either way I still need a signal to time the insert... (Edit: Emitting a signal from the delegates createEditor() function, then calling scheduleDelayedItemsLayout does the trick, you just need to disconnect & reconnect the signal when opening persistent editors)

        JonBJ 1 Reply Last reply
        0
        • R Rhdr

          Found part of the solution: After adding the new blank row you can loop through the QTableView, remove and then re-open the persistent editors. This will re-align their positions correctly, however the operation is costly.

          I am not sure other than removing persistence altogether if there would be a better way? (Edit: If you call scheduleDelayedItemsLayout() https://doc.qt.io/qt-5/qabstractitemview.html#scheduleDelayedItemsLayout then the editors is updated correctly no need for recreating)

          Either way I still need a signal to time the insert... (Edit: Emitting a signal from the delegates createEditor() function, then calling scheduleDelayedItemsLayout does the trick, you just need to disconnect & reconnect the signal when opening persistent editors)

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

          @Rhdr
          If I understand right, you need an "edit signal" before CreateEditor() is called, right?

          So since I too do not see any signal for this, look at your QTableView's editTriggers (https://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop) and implement your own slot(s) on the event(s)/signal(s) which are going to going to take you into edit mode?

          Another possibility is QTableView::edit() slot (https://doc.qt.io/qt-5/qabstractitemview.html#edit)

          Starts editing the item corresponding to the given index if it is editable.

          Does that get called before the CreateEditor()? In which case that might be the signal you were looking for?

          Actually it's not terribly clear to me how/when you do this "extra blank row for adding a row". If you do not always have a blank row there won't be anything for the user to edit, so they must have to click a button? If you do have a blank row sitting there all the time, then the signal you are looking for when to add a new blank line is something about after the user has edited the blank line, for next time around. I leave that to you.

          R 1 Reply Last reply
          1
          • JonBJ JonB

            @Rhdr
            If I understand right, you need an "edit signal" before CreateEditor() is called, right?

            So since I too do not see any signal for this, look at your QTableView's editTriggers (https://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop) and implement your own slot(s) on the event(s)/signal(s) which are going to going to take you into edit mode?

            Another possibility is QTableView::edit() slot (https://doc.qt.io/qt-5/qabstractitemview.html#edit)

            Starts editing the item corresponding to the given index if it is editable.

            Does that get called before the CreateEditor()? In which case that might be the signal you were looking for?

            Actually it's not terribly clear to me how/when you do this "extra blank row for adding a row". If you do not always have a blank row there won't be anything for the user to edit, so they must have to click a button? If you do have a blank row sitting there all the time, then the signal you are looking for when to add a new blank line is something about after the user has edited the blank line, for next time around. I leave that to you.

            R Offline
            R Offline
            Rhdr
            wrote on last edited by Rhdr
            #4

            @JonB thanks for the reply. Similar to MS Access I have a blank row at the bottom at all times, if the user edit it a new blank row appear below it.

            I got it working by:

            1. Overwriting the delegate and emitting a signal from createEditor(),
            2. then inserted the blank record,
            3. then calling scheduleDelayedItemsLayout() on the QTableView to re-allign the editors.
              (My custom model mange the amount of blank records that can be added this way)
              (Also you just need to disconnect & reconnect the signal when opening persistent editors)

            Edit: I still ran into a bunch of quirks,,, however there is a much simpler way to achieve more or less the same effect. Create 2 TableViews and use the bottom one as the "add new record" table. Link both table's QHeaderViews to make sure their columns stay in sync!

            Edit2: Be sure to see VRonin's answer below for a link to a working C++ model that does exactly what the original question asked

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #5

              You can use InsertProxyModel from https://github.com/VSRonin/QtModelUtilities
              Example usage: https://github.com/VSRonin/QtModelUtilities/tree/1.0.0/examples/exam_InsertProxyModel

              Should do exactly what you want but it will probably require a bit of translation from C++ to Python

              If you are reading this in 2059 then maybe I would have found the time to complete the merge of that class in Qt: https://codereview.qt-project.org/c/qt/qtbase/+/236399

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              R 1 Reply Last reply
              2
              • VRoninV VRonin

                You can use InsertProxyModel from https://github.com/VSRonin/QtModelUtilities
                Example usage: https://github.com/VSRonin/QtModelUtilities/tree/1.0.0/examples/exam_InsertProxyModel

                Should do exactly what you want but it will probably require a bit of translation from C++ to Python

                If you are reading this in 2059 then maybe I would have found the time to complete the merge of that class in Qt: https://codereview.qt-project.org/c/qt/qtbase/+/236399

                R Offline
                R Offline
                Rhdr
                wrote on last edited by Rhdr
                #6

                @vronin that looks like exactly it, thanks for the link! The translation shouldn't be a problem, most of the qt documentation is written in c++ anyway. Is there a way to mark your post as the answer instead?

                1 Reply Last reply
                0
                • JonBJ JonB referenced this topic on

                • Login

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