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. Model/View: How to tell an edit delegate to update it's position?
Forum Update on Monday, May 27th 2025

Model/View: How to tell an edit delegate to update it's position?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 533 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.
  • A Offline
    A Offline
    Asperamanca
    wrote on last edited by
    #1

    I have a situation where the edit delegate is not positioned above the cell that is actually edited, but one row below. To the user, it looks as if she were editing the cell in row 3, whereas actually the cell in row 2 is changed.

    Is there any way to tell the delegate to update it's position according to the cell being edited?

    Background:
    I have a rather complex setup: A table view that is connected to a custom-written AbstractItemModel, which obtains the data (already sorted and filtered) from a class running in a separate thread, all in the spirit of high performance and UI responsiveness.

    Because the actual sorting and filtering is running in a separate thread, changes to the sort order arrive asynchronously. That means, if I change a cell value in a column relevant for sorting, I will receive a notification that the sort order has changed through the event loop.

    Much like in Excel, the user should be able to quickly enter values by typing and then pressing <Tab> (jump to next cell to the right) or <Return> (jump to cell below). And the latter is causing trouble.

    When the user edits within the "sorted by" column, any change to the content may trigger sorting - asynchronously. This is easiest to show when multiple rows have the same value in the "sorted by" column. Let's say the following table is sorted by column "Name" in ascending order:

    Name		Source
    Input		F_01
    Input		F_02
    Input		F_03
    Output		F_01
    Output		F_02
    Output		F_03
    

    The user wants to make the names unique, and starts editing in the top row (the '|' indicating the text cursor):

    Name		Source
    Input_01|	F_01
    Input		F_02
    Input		F_03
    Output		F_01
    Output		F_02
    Output		F_03
    

    ..then presses <Return>.
    The value change is committed to the model, and in the "closeEditor" slot, the cell below is selected for editing:

    Name		Source
    Input_01	F_01
    Input|		F_02
    Input		F_03
    Output		F_01
    Output		F_02
    Output		F_03
    

    Now sorting kicks in:

    Name		Source
    Input		F_02
    Input|		F_03
    Input_01	F_01
    Output		F_01
    Output		F_02
    Output		F_03
    

    The edit delegate remains in row 2, but actually edits the item now in row 1.

    The code to select the next cell to edit is basically simple:

        if((model() == nullptr)|| selectedIndexes().isEmpty())
        {
           QTableView::closeEditor(editor, hint);
           return;
        }
    
        //Den selektierten index vor dem Basisklassenaufruf merken
        const QModelIndex selectedIndex = selectedIndexes().first(); //Achtung: eine const & ist hier nicht möglich
        QTableView::closeEditor(editor, hint);
    
        switch(hint)
        {
           case QAbstractItemDelegate::SubmitModelCache:
           {
              int row = selectedIndex.row()+1;
              int column = selectedIndex.column();
              if(row >= model()->rowCount())
              {
                 row = 0;
                 ++column;
              }
              const QModelIndex & newIndex = model()->index(row,column);
              edit(newIndex);
              break;
           }
        }
    

    (removed some checks for corner cases to make it simpler)

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2
      • since sorting is asynchronous, can't you just queue edit(newIndex); so that it's executed after sorting too?
      • do you reimplement QStyledItemDelegate::updateEditorGeometry?

      "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

      A 1 Reply Last reply
      2
      • VRoninV VRonin
        • since sorting is asynchronous, can't you just queue edit(newIndex); so that it's executed after sorting too?
        • do you reimplement QStyledItemDelegate::updateEditorGeometry?
        A Offline
        A Offline
        Asperamanca
        wrote on last edited by
        #3

        @VRonin said in Model/View: How to tell an edit delegate to update it's position?:

        • since sorting is asynchronous, can't you just queue edit(newIndex); so that it's executed after sorting too?
        • do you reimplement QStyledItemDelegate::updateEditorGeometry?
        • I have tried delaying the call to edit (using a 1000 ms single shot timer), but as long as newIndex is determined before sorting, the result is exactly the same (for whatever reason). However, since the item that is actually edited is exactly the one I want, the newIndex seems to be correct.
        • No, updateEditorGeometry is not reimplemented. But that would give me a handle to find out a bit more. Thanks for the hint!
        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