Unable to get selected rows/indexes in QTableView with custom model



  • Hello,
    I have a QTableView. I am trying to implement actions like Insert Above, Insert Below, Delete, etc. To implement these actions I need to know the selected rows in the table.

    Within the action handler, both the lines below return a collection size 0 (even though there are rows selected in the table):

    QModelIndexList selections = this->qTableView->selectionModel()->selectedIndexes();
    QModelIndexList selections1 = this->qTableView->selectionModel()->selectedRows();
    

    I am using a model that is subclass off of QAbstractTableModel.

    On the qTableView, I am also settings these attributes:

    this->qTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    this->qTableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    

    What am I doing wrong? How can I get the selected rows and their indexes in the model?

    Thanks


  • Lifetime Qt Champion

    Hi,

    Can you show the implementation of your custom model ?
    What action handler is that ?
    Does it maybe clear the selection when called ?



  • Hi SGaist,
    I am overriding the following functions in my custom model (not sure if you need the internals):

    int rowCount(const QModelIndex &parent) const override;
        int columnCount(const QModelIndex &parent) const override;
        QVariant data(const QModelIndex &index, int role) const override;
        QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
        Qt::ItemFlags flags(const QModelIndex &index) const override;
        bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
        bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
        bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
        Qt::DropActions supportedDropActions() const override;
        bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
    

    I am installing a right-click customContextMenuRequested menu on the QTableView. To this QMenu, I add a QAction. The QAction is connected to a function in my class like this:

    connect(insertQuoteRowAbove, SIGNAL(triggered()), this, SLOT(insertQuoteRowAbove()));
    

    In the insertQuoteRowAbove function, I get empty collection when I call:

    QModelIndexList selections = this->qTableView->selectionModel()->selectedIndexes();
    QModelIndexList selections1 = this->qTableView->selectionModel()->selectedRows();
    

    Thanks


  • Lifetime Qt Champion

    Then a maybe silly question but are you explicitly selecting a row before right clicking on it ?

    That said, you have the position of the mouse pointer given by the customContextMenuRequested signal, so you can use that to get the row under the mouse cursor.



  • Yes, even I select the row first, then right click on it, I still get empty collections when I execute the selectedRows and selectedIndexes on the selectionModel.

    With regards to your suggestion about using the position of the mouse pointer:
    I have both these lines:

    QModelIndex index = this->qTableView->indexAt(pos);
    

    and then

    contextMenu->popup(this->qTableView->viewport()->mapToGlobal(pos));
    

    I believe both of those are necessary. There are some inconsistencies in the column resolution, but the row resolution seems to be reliable. The problem I have taking this path is: How do I send the position or the QModelIndex into my insertQuoteRowAbove handler? Since the triggered signal does not have a QModelIndex parameter, I get the signal-slot mismatch error.

    connect(insertQuoteRowAbove, SIGNAL(triggered()), this, SLOT(insertQuoteRowAbove()));
    

    QUESTIONS:
    Is it cause for concern that my selectionModel is not tracking the selections? Any tips on how I can figure this out?

    Secondly, how do I get around the signal-slot mismatch if I have to go the route of passing the position/index?. I was able to figure out the answer to this question. signalmapper is the way to pass parameters into the slot. I am focussed on figuring out why my selectionModel is not tracking my selections.

    Thanks SGaist.


  • Lifetime Qt Champion

    You can make that index a member of your class or use a lambda.

    Yes, it's pretty strange and you should investigate that.



  • After setting up the Qt sources, I was able to debug into this problem. QtCreator and gdb are extremely unreliable. Debugging is like a minefield, bcos any one click could cause the debugger to exit.

    In any case, after stepping through the code, I could see that the selection was being applied in the selection model. When querying for the selectedRows or selectedIndexes the list was empty. It felt like I was accessing different selectionModels, and that is what the problem turned out to be. My cached selectionModel reference was not for the table that was being shown. Hence the empty selections.

    This was my stupid mistake. A stable debugging environment would make it so easy to find my own stupid mistakes. I fear that I will never has a stable debugging environment with Qt.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.