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. TableView selectRow immediately after model reset doesn't work as expected
Qt 6.11 is out! See what's new in the release blog

TableView selectRow immediately after model reset doesn't work as expected

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 1.6k Views 1 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.
  • N Offline
    N Offline
    Nanuk_2018
    wrote on last edited by Nanuk_2018
    #1

    Hi,

    I've been investing the better part of a day trying to figure out what is wrong with my otherwise fully functional QTableView/QTabelModel. The problem shows up when during selecting the tab that contains the view. In the context of the tab current changed slot, I update the model (which in turns call a beginModelReset and endModelReset) and I want to select the first row of the TableView. Now if I call tableView->selectRow(0) immediately after the model reset. Nothing happens... but if I do the same call for example when I click on a button somewhere else in my UI then it works fine. I managed to duplicate the problem with the fetchMore example from Qt.

    Should I be waiting for the view to finish its refresh and if so how can I do that? I must be missing something trivial but I can't find the answer anywhere else.

    Kind regards

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

      I would connect (QueuedConnection) to QAbstractItemModel::modelReset() to make sure the internals of the model and view had time to react on the new state.

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

      N 1 Reply Last reply
      2
      • Christian EhrlicherC Christian Ehrlicher

        I would connect (QueuedConnection) to QAbstractItemModel::modelReset() to make sure the internals of the model and view had time to react on the new state.

        N Offline
        N Offline
        Nanuk_2018
        wrote on last edited by
        #3

        @Christian-Ehrlicher Thanks for your help and quick reply, sadly enough this is still not working... I've implemented it in the fetchMore example, this is seriously frustrating as it should be such a simple thing to accomplish. Any other ideas?

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

          I don't see a reason why it should not work. What did you modify in the example so we can reproduce it?

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

          N 1 Reply Last reply
          1
          • Christian EhrlicherC Christian Ehrlicher

            I don't see a reason why it should not work. What did you modify in the example so we can reproduce it?

            N Offline
            N Offline
            Nanuk_2018
            wrote on last edited by Nanuk_2018
            #5

            @Christian-Ehrlicher Here it is:
            {

            #include "filelistmodel.h"
            #include "window.h"
            
            #include <QtWidgets>
            
             Window::Window(QWidget *parent)
               : QWidget(parent)
             {
               FileListModel *model = new FileListModel(this);
               model->setDirPath(QLibraryInfo::location(QLibraryInfo::PrefixPath));
            
               QLabel *label = new QLabel(tr("&Directory:"));
               QLineEdit *lineEdit = new QLineEdit;
               label->setBuddy(lineEdit);
            
               view = new QListView;
               view->setSelectionBehavior(QAbstractItemView::SelectRows);
               view->setModel(model);
            
               logViewer = new QTextBrowser;
               logViewer->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
            
               connect(lineEdit, &QLineEdit::textChanged,
                       model, &FileListModel::setDirPath);
               connect(lineEdit, &QLineEdit::textChanged,
                       logViewer, &QTextEdit::clear);
               connect(model, &FileListModel::numberPopulated,
                       this, &Window::updateLog);
               connect(model, &FileListModel::modelReset,
                       this, &Window::selectARow);
               connect(view, &QListView::clicked,
                       this, &Window::selectARow);
            
               QGridLayout *layout = new QGridLayout;
               layout->addWidget(label, 0, 0);
               layout->addWidget(lineEdit, 0, 1);
               layout->addWidget(view, 1, 0, 1, 2);
               layout->addWidget(logViewer, 2, 0, 1, 2);
            
               setLayout(layout);
               setWindowTitle(tr("Fetch More Example"));
               }
            
              void Window::updateLog(int number)
             {
                 logViewer->append(tr("%1 items added.").arg(number));
             }
            
            void Window::selectARow()
            {
                QModelIndex i = view->model()->index(1,0);
                if(i.isValid())
                    view->setCurrentIndex(i);
            }
            

            I've connected the selectARow with two signals, one being the modelReset of the model and the other one being the clicked of the view to confirm my code indeed works as expected. This is just a quick and dirty demo, and I know there are corner cases where this might fail but it demonstrates the behavior I observe. Of course the prototypes for the selectARow slot needs to be added to the .h file, I didn't include the latter to keep this long post as short as possible.

            Any help pointing me in the right direction would be much appreciated!

            Kind regards

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

              In the example you posted the problem comes from the fact that view->model()->index(1,0); does not exist as it was not loaded yet.

              If you reimplement index() in the model with something like this, you'll see everything works fine

              QModelIndex index(int row, int column, const QModelIndex &parent) const override {
                      if(parent.isValid() || row<0 || column!=0)
                          return QModelIndex();
                      while(row>=rowCount() && canFetchMore(QModelIndex()))
                          const_cast<FileListModel*>(this)->fetchMore(QModelIndex());
                      if(row>=rowCount())
                          return QModelIndex();
                      return createIndex(row, column);
                  }
              

              Yes, this is a very bad implementation of index() but it's just to show where the problem is

              "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

              N 1 Reply Last reply
              2
              • VRoninV VRonin

                In the example you posted the problem comes from the fact that view->model()->index(1,0); does not exist as it was not loaded yet.

                If you reimplement index() in the model with something like this, you'll see everything works fine

                QModelIndex index(int row, int column, const QModelIndex &parent) const override {
                        if(parent.isValid() || row<0 || column!=0)
                            return QModelIndex();
                        while(row>=rowCount() && canFetchMore(QModelIndex()))
                            const_cast<FileListModel*>(this)->fetchMore(QModelIndex());
                        if(row>=rowCount())
                            return QModelIndex();
                        return createIndex(row, column);
                    }
                

                Yes, this is a very bad implementation of index() but it's just to show where the problem is

                N Offline
                N Offline
                Nanuk_2018
                wrote on last edited by
                #7

                @VRonin Thanks for your help but it still isn't working. I've implemented index as you suggested but the view stubbornly refuses to select the proper entry after a model reset.... It seems to be independent of the model I use since as highlighted in the post title, I've started with a table model and now reverted back to the list model and still see the exact same behavior.
                Am I trying to do something that was not intended to be done with the framework?
                I'm using the default QListView/QTableView perhaps I need to derive my own and reimplement some functions to accomplish what I'm looking for...

                Again, any help or pointer to documentation or existing examples really appreciated

                Kind regards

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

                  I tested the implementation above and works with the fetchMore example from Qt.
                  I suspect you have something similar in your model. Since there's no such thing as a QTabelModel, could you post your model implementation so we can have a look at what's going wrong?

                  "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

                  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