Yarram Yarram - 1 year ago 305
C++ Question

How to select previous row in a QTreeView?

I have a QTreeView with single column and multiple row (lets say 5 rows). What I want to achieve is that if I select a row, I want to re-select previous row on some condition.

Here is the code I have:


#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QModelIndex>
#include <QHBoxLayout>

class MyWidget : public QWidget

MyWidget(QWidget *parent = 0);

private slots:
void _OnTreeViewCurrentRowChanged(const QModelIndex &rcqmiCurrIndex,
const QModelIndex &rcqmiPrevIndex);

QHBoxLayout *_pLayout;

QTreeView *_pTreeView;
QStandardItemModel *_pStandardItemModel;
QStandardItem *_pStandardItem;



#include "MyWidget.h"

static bool bCondition = false;

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
_pLayout = new QHBoxLayout(this);

_pTreeView = new QTreeView(this);
_pStandardItemModel = new QStandardItemModel(_pTreeView);
_pStandardItem = new QStandardItem("Column A");


_pStandardItemModel->setHorizontalHeaderItem(0, _pStandardItem);


// add rows

for (int i = 0; i < 5; ++i)
QStandardItem *pStandardItem = new QStandardItem(
QString("Row: %1").arg(i + 1));



// update view

SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)),
this, SLOT(_OnTreeViewCurrentRowChanged(const QModelIndex &,
const QModelIndex &)));



void MyWidget::_OnTreeViewCurrentRowChanged(
const QModelIndex &rcqmiCurrIndex, const QModelIndex &rcqmiPrevIndex)
if (bCondition) // some condition

// select previous index
rcqmiPrevIndex, QItemSelectionModel::SelectCurrent);


// update view

bCondition = !bCondition;

In _OnTreeViewCurrentRowChanged(...), I can see that "selection" of tree view's selection model is updated with
QItemSelectionModel::setCurrentIndex(rcqmiPrevIndex, QItemSelectionModel::SelectCurrent);
but the tree view's row selection is NOT updated, still the
is selected.

What am I missing here?

Any help is much appreciated. Thanks in advance.

Answer Source

Use the QItemSelectionModel::select() method.

_pTreeView->selectionModel()->select(rcqmiPrevIndex, QItemSelectionModel::ClearAndSelect);


There is probably another problem: The _OnTreeViewCurrentRowChanged(...) is probably a slot invoked when the current row is changed, right? That means you are changing the selection twice in single event. This is not a good idea. Use the QTimer to perform the selection in the next event loop cycle:

// lambda
auto func = [this, rcqmiPrevIndex](){
    _pTreeView->selectionModel()->select(rcqmiPrevIndex, QItemSelectionModel::ClearAndSelect);

// A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system's event queue have been processed.
QTimer::singleShot(0, func);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download