Reputation: 980
I have hit a problem with QTableView (Qt version 5.12.10). I have create a very basic table class which just has the the following code in the class constructor:
setModel(pModel); // pModel is of a class derived from QAbstractTableModel
setWindowTitle("The Title");
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::ExtendedSelection);
When I click on the left most column (not the id column) where it says 2, it will select the whole of row 2.
When I shift click on row 3 it also selects the whole of row 3.
When I shift click on row 4 in the first name column (any column except the left most) it selects row 4 and deselects row 2.
According to the documentation tis could be expected behaviour, but if all clicks are performed in the Name column then row 2 is not deselected.
Further after doing the above clicking on row 8 and the left most column reselects row 1 where as row 8 anywhere else does not reselect row 1.
It appears that the left most column has a selection value that the rest of the table can't fully access.
Questions:
Code: main.cpp
#include <sstream>
#include <QWidget>
#include <QApplication>
#include <QTableView>
#include "cmodeldata.h"
#include "cqtableview.h"
/// Display the row from a QItemSelection
std::string dumpQItemSelection (const QItemSelection& selection)
{
int lastRow = -1;
std::stringstream output;
output << "(";
for (auto index : selection.indexes())
{
if (index.row() != lastRow)
{
lastRow = index.row();
output << index.row() << ",";
}
}
output << ")";
return output.str();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CModelData m_model;
CQTableView *m_table = new CQTableView (&m_model);
m_table->show();
return a.exec();
}
cqtableview.h
#ifndef CQTABLEVIEW_H
#define CQTABLEVIEW_H
#include <QWidget>
#include <QTableView>
#include "cmodeldata.h"
class CQTableView : public QTableView
{
Q_OBJECT
public:
explicit CQTableView(CModelData* pModel = nullptr, QWidget *parent = nullptr)
: QTableView(parent)
{
setModel(pModel);
setWindowTitle("The Title");
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::ExtendedSelection);
}
public slots:
public:
};
#endif // CQTABLEVIEW_H
cmodeldata.h
#ifndef CMODELDATA_H
#define CMODELDATA_H
#include <QAbstractTableModel>
#include <QStringListModel>
class CModelData : public QAbstractTableModel
{
Q_OBJECT
public:
enum class EColumns
{ // The order of the columns
eId = 0
, eFirstName
, eLastName
, eEmail
, ePhone
, eColumnCount
};
public:
CModelData(QObject *parent = nullptr);
/// Get the number of rows in the data source
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
/// Get the number of columns in the data source
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
/// Return a cell of data
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
/// Return a cell of data relevent to the header
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
/// Add a row of data
bool addRow (const int i, const QString& fn, const QString& ln, const QString& e, const QString& pn);
private:
struct DataRow
{ // This is a row of data
int id;
QString firstName;
QString lastName;
QString email;
QString phone;
DataRow (const int i = 0, const QString& fn = "", const QString& ln = "", const QString& e = "", const QString& pn = "")
: id(i), firstName(fn), lastName(ln), email(e), phone(pn)
{}
};
QVector<DataRow> m_rows;
};
#endif // CMODELDATA_H
cmodeldata.cpp
#include "cmodeldata.h"
CModelData::CModelData(QObject* pParent)
: QAbstractTableModel(pParent)
{
addRow(0, "Alan", "Alanson", "[email protected]", "0111 111111");
addRow(1, "Bob", "Brown", "[email protected]", "0111 222222");
addRow(2, "Charlie", "Carlson", "[email protected]", "0111 333333");
addRow(3, "Dave", "Davis", "[email protected]", "0111 444444");
addRow(4, "Eric", "Ericson", "[email protected]", "0111 555555");
addRow(5, "Frank", "Fallows", "[email protected]", "0111 666666");
addRow(6, "Geoff", "Geofferson", "[email protected]", "0111 777777");
addRow(7, "Hugo", "Hadron", "[email protected]", "0111 888888");
addRow(8, "Ian", "Indigo", "[email protected]", "0111 999999");
addRow(9, "James", "Jamerson", "[email protected]", "0111 000000");
}
int CModelData::rowCount(const QModelIndex & /*parent*/) const
{
return m_rows.count();
}
int CModelData::columnCount(const QModelIndex & /*parent*/) const
{
return static_cast<int>(EColumns::eColumnCount);
}
QVariant CModelData::data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole)
{
/// return QString("Row%1, Column%2").arg(index.row() + 1).arg(index.column() +1);
for (auto& item : m_rows)
{
if (item.id == index.row())
{
switch (index.column())
{
case static_cast<int>(EColumns::eId):
return item.id;
case static_cast<int>(EColumns::eFirstName):
return item.firstName;
case static_cast<int>(EColumns::eLastName):
return item.lastName;
case static_cast<int>(EColumns::eEmail):
return item.email;
case static_cast<int>(EColumns::ePhone):
return item.phone;
default:
return QVariant();
}
}
}
}
return QVariant();
}
QVariant CModelData::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
switch (section)
{
case static_cast<int>(EColumns::eId):
return QString("Id");
case static_cast<int>(EColumns::eFirstName):
return QString("First Name");
case static_cast<int>(EColumns::eLastName):
return QString("Last Name");
case static_cast<int>(EColumns::eEmail):
return QString("Email");
case static_cast<int>(EColumns::ePhone):
return QString("Phone");
}
}
// return QAbstractTableModel::headerData(section, orientation, role);
return QAbstractTableModel::headerData(section, orientation, role);
}
bool CModelData::addRow (const int i, const QString& fn, const QString& ln, const QString& e, const QString& pn)
{
m_rows.append(DataRow(i, fn, ln, e, pn));
return true;
}
Upvotes: 0
Views: 520
Reputation: 958
It's a bug in Qt, I've created a bug report here: https://bugreports.qt.io/browse/QTBUG-92561
Upvotes: 1