Mark Vargas
Mark Vargas

Reputation: 25

How can I set the initial index for Shift + click selection in Qt QTableView?

My issue is that after Ctrl + click deselect of an item. It became the initial index of the following Shift + click select.

What I would like to happen is set the initial index of the Shift selection to index 0.

For example:

#include <QApplication>
#include <QtWidgets>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QStringListModel model({"1", "2", "3", "4", "5", "6", "7", "8", "9"});
    QTableView view;
    view.horizontalHeader()->setVisible(false);
    view.setSelectionBehavior(QAbstractItemView::SelectRows);
    view.setSelectionMode(QAbstractItemView::ExtendedSelection);
    view.setModel(&model);
    view.show();

    return a.exec();
}
  1. Select row header 2
    enter image description here

  2. Deselect row header 2 using Ctrl + click
    enter image description here

  3. Shift + click row header 5
    enter image description here

Expected result: Row 1, 2, 3, 4, and 5 are selected.

Actual result: Rows 2, 3, 4, and 5 are selected.

Is there any way to produce the expected result?

Upvotes: 0

Views: 490

Answers (1)

Serhiy Kulish
Serhiy Kulish

Reputation: 1122

You should subclass QTableView for this purpose. Here is small example tested for Qt4. For Qt5 it should be pretty similar. Header:

#ifndef CUSTOMTABLEWIDGET_H
#define CUSTOMTABLEWIDGET_H

#include <QTableView>

class CustomTableWidget : public QTableView
{
    Q_OBJECT
public:
    explicit CustomTableWidget(QWidget *parent = 0);

protected:
    void mousePressEvent(QMouseEvent *event);
};

#endif // CUSTOMTABLEWIDGET_H

Cpp:

#include "customtablewidget.h"

#include <QMouseEvent>
#include <QItemSelectionModel>

CustomTableWidget::CustomTableWidget(QWidget *parent) :
    QTableView(parent)
{
}

void CustomTableWidget::mousePressEvent(QMouseEvent *event)
{
    QModelIndex clickedIndex = this->indexAt(QPoint(event->x(), event->y()));

    bool isShiftClicked = Qt::LeftButton == event->button() && (event->modifiers() & Qt::ShiftModifier);
    if (clickedIndex.isValid() && isShiftClicked)
    {
        bool isRowSelected = this->selectionModel()->isRowSelected(clickedIndex.row(),
                                                                   clickedIndex.parent());
        if (!isRowSelected)
        {
            QModelIndex initialIndex = this->model()->index(0, 0);
            this->selectionModel()->clear();
            this->selectionModel()->select(QItemSelection(initialIndex, clickedIndex),
                                           QItemSelectionModel::Select);
            event->accept();
            return;
        }
    }

    QTableView::mousePressEvent(event);
}

Upvotes: 2

Related Questions