简述
使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点:
- 三态:不选/半选/全选
- 自定义风格(样式)
下面我们介绍一下常见的实现方式:
编辑委托。
方式:利用委托重载createEditor(),激活QCheckBox。
特点:必须双击/选中,才能显示CheckBox控件。一般不满足实际中的直接显示的需要。使用QTableView的setIndexWidget(const QModelIndex &index, QWidget *widget)来实现。
此功能用来显示可视区域内对应一个数据项的静态内容。如果想显示自定义的动态内容或执行自定义编辑器部件,子类化QItemDelegate代替。也就是说,这只适合做静态数据的显示,不适合做一些插入、更新、删除操作的数据显示。自定义模型QAbstractTableModel,通过flags()函数来实现。
方式:通过将flags()设置为Qt::ItemIsUserCheckable实现可选中,然后配合setData()与data()来实现。
特点:直接显示,可定义样式,默认左对齐,很难实现居中、右对齐。自定义委托QAbstractItemDelegate,通过paint()函数来实现。
方式:通过控制editorEvent()实现鼠标的点击进行全选/半选/不选,然后由paint()实时绘制。
特点:这种方式比较复杂,但适合扩展,除了可以嵌入复选框,还可以绘制其它控件-按钮、图片等。
效果
下面我们来介绍如何利用QAbstractTableModel的flags()函数来实现复选功能。
QAbstractTableModel
源码
table_model.cpp
#define CHECK_BOX_COLUMN 0
#define File_PATH_COLUMN 1
TableModel::TableModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
TableModel::~TableModel()
{
}
// 更新表格数据
void TableModel::updateData(QList<FileRecord> recordList)
{
m_recordList = recordList;
beginResetModel();
endResetModel();
}
// 行数
int TableModel::rowCount(const QModelIndex &parent) const
{
return m_recordList.count();
}
// 列数
int TableModel::columnCount(const QModelIndex &parent) const
{
return 2;
}
// 设置表格项数据
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
int nColumn = index.column();
FileRecord record = m_recordList.at(index.row());
switch (role)
{