C++ Qt QTableVew选择多行
我发现QTableView Qt版本5.12.10有问题。我创建了一个非常基本的表类,它在类构造函数中只有以下代码: 当我点击最左边的列,而不是id列,它说2,它会选择整个第2行。 当我按住shift键并单击第3行时,它也会选择整个第3行。 当我按住shift键并单击“名字”列中的第4行时,除最左边的列外,它会选择第4行并取消选择第2行C++ Qt QTableVew选择多行,c++,qt,qtableview,C++,Qt,Qtableview,我发现QTableView Qt版本5.12.10有问题。我创建了一个非常基本的表类,它在类构造函数中只有以下代码: 当我点击最左边的列,而不是id列,它说2,它会选择整个第2行。 当我按住shift键并单击第3行时,它也会选择整个第3行。 当我按住shift键并单击“名字”列中的第4行时,除最左边的列外,它会选择第4行并取消选择第2行 根据文档,这可能是预期的行为,但如果在名称列中执行所有单击,则不会取消选择第2行 执行上述操作后,单击第8行,最左边的列将重新选择第1行,而其他任何位置的第8行
根据文档,这可能是预期的行为,但如果在名称列中执行所有单击,则不会取消选择第2行 执行上述操作后,单击第8行,最左边的列将重新选择第1行,而其他任何位置的第8行都不会重新选择第1行 最左边的列似乎有一个表的其余部分无法完全访问的选择值 问题: 我做错什么了吗? 我是否误解了记录在案的行为? 有人知道有没有办法让双方以同样的方式工作? 代码: main.cpp 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", "alan@email.com", "0111 111111");
addRow(1, "Bob", "Brown", "bob@email.com", "0111 222222");
addRow(2, "Charlie", "Carlson", "charlie@email.com", "0111 333333");
addRow(3, "Dave", "Davis", "dave@email.com", "0111 444444");
addRow(4, "Eric", "Ericson", "eric@email.com", "0111 555555");
addRow(5, "Frank", "Fallows", "frank@email.com", "0111 666666");
addRow(6, "Geoff", "Geofferson", "geoff@email.com", "0111 777777");
addRow(7, "Hugo", "Hadron", "hugo@email.com", "0111 888888");
addRow(8, "Ian", "Indigo", "ian@email.com", "0111 999999");
addRow(9, "James", "Jamerson", "james@email.com", "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;
}
这是Qt中的一个bug,我在这里创建了一个bug报告:根据文档,当按住Shift键时,会选择连续的行。但是,通过按住CTRL键,您应该能够选择任意行。同意,因此在本例中,我应该选择第2到第4行。如果单击第2列而不是最左边的列,则会发生这种情况。我不确定我是否做错了什么,或者左列处理shift单击的方式是否存在错误。您是否尝试过单击2,然后shift单击“4”?那有什么用?它是否选择了所有三行?当然,Qt只是一个非常大和复杂的框架,当然也不能排除bug。您的模型在第一列返回什么标志?@RefugnicEternium单击2,然后按住shift键单击4左列,选择第2到第4行。但是,单击下面或上面任何一行的第3列都会导致问题。有一种方法可以阻止这种情况发生,方法是按住shift键并在其他列上单击4次,但这并不是我们可以要求用户真正做的事情。我更喜欢你的简单示例:
#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
#include "cmodeldata.h"
CModelData::CModelData(QObject* pParent)
: QAbstractTableModel(pParent)
{
addRow(0, "Alan", "Alanson", "alan@email.com", "0111 111111");
addRow(1, "Bob", "Brown", "bob@email.com", "0111 222222");
addRow(2, "Charlie", "Carlson", "charlie@email.com", "0111 333333");
addRow(3, "Dave", "Davis", "dave@email.com", "0111 444444");
addRow(4, "Eric", "Ericson", "eric@email.com", "0111 555555");
addRow(5, "Frank", "Fallows", "frank@email.com", "0111 666666");
addRow(6, "Geoff", "Geofferson", "geoff@email.com", "0111 777777");
addRow(7, "Hugo", "Hadron", "hugo@email.com", "0111 888888");
addRow(8, "Ian", "Indigo", "ian@email.com", "0111 999999");
addRow(9, "James", "Jamerson", "james@email.com", "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;
}