如何在QTreeView中选择前一行

How to select previous row in a QTreeView?

本文关键字:一行 选择 QTreeView      更新时间:2023-10-16

我有一个QTreeView单列和多行(让我们说5行)。我想要实现的是,如果我选择了一行,我想在某些条件下重新选择前一行。

下面是我的代码:

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QModelIndex>
#include <QHBoxLayout>
class MyWidget : public QWidget
{
    Q_OBJECT
public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();
private slots:
    void _OnTreeViewCurrentRowChanged(const QModelIndex &rcqmiCurrIndex,
        const QModelIndex &rcqmiPrevIndex);
private:
    QHBoxLayout *_pLayout;
    QTreeView *_pTreeView;
    QStandardItemModel *_pStandardItemModel;
    QStandardItem *_pStandardItem;
};
#endif

MyWidget.cpp

#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");
    _pLayout->addWidget(_pTreeView);
    _pStandardItemModel->setColumnCount(1);
    _pStandardItemModel->setHorizontalHeaderItem(0, _pStandardItem);
    _pTreeView->setModel(_pStandardItemModel);
    _pTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
    _pTreeView->setSelectionMode(QAbstractItemView::SingleSelection);
    _pTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    // add rows
    _pTreeView->selectionModel()->blockSignals(true);
    for (int i = 0; i < 5; ++i)
    {
        QStandardItem *pStandardItem = new QStandardItem(
            QString("Row: %1").arg(i + 1));
        _pStandardItemModel->appendRow(pStandardItem);
    }
    _pTreeView->selectionModel()->blockSignals(false);
    // update view
    _pTreeView->viewport()->update();
    connect(_pTreeView->selectionModel(),
        SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)),
        this, SLOT(_OnTreeViewCurrentRowChanged(const QModelIndex &,
        const QModelIndex &)));
}
MyWidget::~MyWidget()
{
}
void MyWidget::_OnTreeViewCurrentRowChanged(
    const QModelIndex &rcqmiCurrIndex, const QModelIndex &rcqmiPrevIndex)
{
    if (bCondition) // some condition
    {
        _pTreeView->selectionModel()->blockSignals(true);
        // select previous index
        _pTreeView->selectionModel()->setCurrentIndex(
            rcqmiPrevIndex, QItemSelectionModel::SelectCurrent);
        _pTreeView->selectionModel()->blockSignals(false);
        // update view
        _pTreeView->viewport()->update();
    }
    bCondition = !bCondition;
}

_OnTreeViewCurrentRowChanged(…)中,我可以看到树视图的选择模型的"选择"与QItemSelectionModel::setCurrentIndex(rcqmiPrevIndex, QItemSelectionModel::SelectCurrent);更新,但树视图的行选择未更新,仍然选择rcqmiCurrIndex

我在这里错过了什么?

任何帮助都是非常感激的。

使用QItemSelectionModel::select()方法

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

编辑

可能还有另一个问题:_OnTreeViewCurrentRowChanged(...)可能是当前行更改时调用的插槽,对吗?这意味着您在单个事件中更改了两次选择。这不是一个好主意。使用QTimer在下一个事件循环周期中执行选择:

// 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);