Qt之QTableView添加复选框(QAbstractItemDelegate)
简述
上节分享了使用自定义模型QAbstractTableModel来实现复选框。下面我们来介绍另外一种方式:
自定义委托-QAbstractItemDelegate。
效果
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)
{
case Qt::DisplayRole:
{
if (nColumn == File_PATH_COLUMN)
{
record.strFilePath = value.toString();
m_recordList.replace(index.row(), record);
emit dataChanged(index, index);
return true;
}
}
case Qt::CheckStateRole:
case Qt::UserRole:
{
if (nColumn == CHECK_BOX_COLUMN)
{
record.bChecked = value.toBool();
m_recordList.replace(index.row(), record);
emit dataChanged(index, index);
return true;
}
}
default:
return false;
}
return false;
}
// 表格项数据
QVariant TableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
int nRow = index.row();
int nColumn = index.column();
FileRecord record = m_recordList.at(nRow);
switch (role)
{
case Qt::TextColorRole:
return QColor(Qt::white);
case Qt::TextAlignmentRole:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::DisplayRole:
{
if (nColumn == File_PATH_COLUMN)
return record.strFilePath;
return "";
}
case Qt::UserRole:
{
if (nColumn == CHECK_BOX_COLUMN)
return record.bChecked;
}
default:
return QVariant();
}
return QVariant();
}
// 表头数据
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
switch (role)
{
case Qt::TextAlignmentRole:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::DisplayRole:
{
if (orientation == Qt::Horizontal)
{
if (section == CHECK_BOX_COLUMN)
return QStringLiteral("状态");
if (section == File_PATH_COLUMN)
return QStringLiteral("文件路径");
}
}
default:
return QVariant();
}
return QVariant();
}
// 表格可选中、可复选
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return QAbstractItemModel::flags(index);
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
return flags;
}
接口说明
updateData
主要用于更新数据,刷新界面。data
用来显示数据,根据角色(颜色、文本、对齐方式、选中状态等)判断需要显示的内容。setData
用来设置数据,根据角色(颜色、文本、对齐方式、选中状态等)判断需要设置的内容。headerData
用来显示水平/垂直表头的数据。flags
用来设置单元格的标志(可用、可选中、可复选等)。
QStyledItemDelegate
源码
CheckBoxDelegate::CheckBoxDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
CheckBoxDelegate::~CheckBoxDelegate()
{
}
// 绘制复选框
void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
QStyledItemDelegate::paint(painter, viewOption, index);
if (index.column() == CHECK_BOX_COLUMN)
{
bool data = index.model()->data(index, Qt::UserRole).toBool();
QStyleOptionButton checkBoxStyle;
checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;
checkBoxStyle.state |= QStyle::State_Enabled;
checkBoxStyle.iconSize = QSize(20, 20);
checkBoxStyle.rect = option.rect;
QCheckBox checkBox;
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, &checkBox);
}
}
// 响应鼠标事件,更新数据
bool CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
QRect decorationRect = option.rect;
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (event->type() == QEvent::MouseButtonPress && decorationRect.contains(mouseEvent->pos()))
{
if (index.column() == CHECK_BOX_COLUMN)
{
bool data = model->data(index, Qt::UserRole).toBool();
model->setData(index, !data, Qt::UserRole);
}
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
接口说明
paint
用来设置表格样式,绘制复选框-状态、大小、显示区域等。editorEvent
用来设置数据,响应鼠标事件,判断当前选中状态,互相切换。
样式
复选框样式:
QCheckBox{
spacing: 5px;
color: white;
}
QCheckBox::indicator {
width: 17px;
height: 17px;
}
QCheckBox::indicator:enabled:unchecked {
image: url(:/Images/checkBox);
}
QCheckBox::indicator:enabled:unchecked:hover {
image: url(:/Images/checkBoxHover);
}
QCheckBox::indicator:enabled:unchecked:pressed {
image: url(:/Images/checkBoxPressed);
}
QCheckBox::indicator:enabled:checked {
image: url(:/Images/checkBoxChecked);
}
QCheckBox::indicator:enabled:checked:hover {
image: url(:/Images/checkBoxCheckedHover);
}
QCheckBox::indicator:enabled:checked:pressed {
image: url(:/Images/checkBoxCheckedPressed);
}
QCheckBox::indicator:enabled:indeterminate {
image: url(:/Images/checkBoxIndeterminate);
}
QCheckBox::indicator:enabled:indeterminate:hover {
image: url(:/Images/checkBoxIndeterminateHover);
}
QCheckBox::indicator:enabled:indeterminate:pressed {
image: url(:/Images/checkBoxIndeterminatePressed);
}
使用
QTableView *pTableView = new QTableView(this);
TableModel *pModel = new TableModel(this);
CheckBoxDelegate *pDelegate = new CheckBoxDelegate(this);
// 设置单行选中、最后一列拉伸、表头不高亮、无边框等
pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
pTableView->horizontalHeader()->setStretchLastSection(true);
pTableView->horizontalHeader()->setHighlightSections(false);
pTableView->verticalHeader()->setVisible(false);
pTableView->setShowGrid(false);
pTableView->setFrameShape(QFrame::NoFrame);
pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
pTableView->setModel(pModel);
pTableView->setItemDelegate(pDelegate);
// 加载数据、更新界面
QList<FileRecord> recordList;
for (int i = 0; i < 5; ++i)
{
FileRecord record;
record.bChecked = false;
record.strFilePath = QString("E:/Qt/image_%1.png").arg(i + 1);
recordList.append(record);
}
pModel->updateData(recordList);
Qt之QTableView添加复选框(QAbstractItemDelegate)的更多相关文章
- Qt之QTableView添加复选框(QAbstractTableModel)
简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...
- Qt之QHeaderView添加复选框
简述 前面分享了QTableView中如何添加复选框.本节主要介绍QTableView中的表头-QHeaderView添加复选框的功能,下面以水平表头为例,垂直表头类似! 简述 效果 QHeaderV ...
- PyQt5之 QTableView 添加复选框(自定义委托)
import sys from untitled import Ui_Form from PyQt5.QtWidgets import QApplication, QWidget, QStyleOpt ...
- Qt之QHeaderView加入复选框
简述 前面分享了QTableView中怎样加入复选框. 本节主要介绍QTableView中的表头-QHeaderView加入复选框的功能,以下以水平表头为例.垂直表头相似! 简述 效果 QHeader ...
- 组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)
组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得. ...
- QListWidget的QComboBox下拉列表添加复选框及消息处理
要在QComboBox下拉列表项中添加复选框,并进行消息处理,在网上搜索了很久没有找到太多有用的信息和实际的例子,但从中还是找到了一些提示性的资料,根据这些简短的介绍,最终实现了这个功能. QComb ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 添加复选框
jQuery EasyUI 数据网格 - 添加复选框 本实例演示如何放置一个复选框列到数据网格(DataGrid).通过复选框,用户将可以选择 选中/取消选中 网格行数据. 为了添加一个复选框列,我们 ...
- dojo:为数据表格添加复选框
一.添加复选框 此时应该选用EnhancedGrid,而不是普通的DataGrid.添加复选框需要设置EnhancedGrid的plugins属性,如下: gridLayout =[{ default ...
- DateGridView标题列头添加复选框
第一:添加列标题时,添加两个空格——用于显示复选框: 第二:实现列标题添加复选框,代码如下: private void AddCheckeBoxToDGVHeader(DataGridView dgv ...
随机推荐
- 【技术贴】解决bug mantisbt APPLICATION ERROR #1502 没有找到类别
解决bug mantisAPPLICATION ERROR #1502 没有找到类别 mantisbt出现1502问题解决:引起问题的原因:当提交的问题有分类,此时删除此分类,就会出现下面的情况.问题 ...
- uva 10617
当s[i] = s[j] dp[i][j] = 1+dp[i+1][j-1]+dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1] = 1+dp[i][j-1]+dp[i+1][j ...
- sql中临时表的创建和使用【本文转自多人博客】
本模块原网址:http://www.cnblogs.com/jeffwongishandsome/archive/2009/08/05/1526466.html 原作者:Jeff Wong 1.创建方 ...
- php数组函数序列之array_unshift() 在数组开头插入一个或多个元素
array_unshift() 函数在数组开头插入一个或多个元素.被加上的元素作为一个整体添加,这些元素在数组中的顺序和在参数中的顺序一样 array_unshift()定义和用法 array_uns ...
- cojs 疯狂的粉刷匠 疯狂的斐波那契 题解报告
疯狂的斐波那契 学习了一些奇怪的东西之后出的题目 最外层要模p是显然的,然而内层并不能模p 那么模什么呢,显然是模斐波那契的循环节 那么我们可以一层层的求出每层的斐波那契循环节 之后在从内向外用矩阵乘 ...
- Java学习笔记(二)UML基础
用例图:代表系统的一个功能模块,仅仅是系统功能的描述.用例图包括:用例.角色.角色和用例之间的关系以及系统内用例之间的关系. 类图:表示系统中包含哪些实体,各实体之间如何关联. 类图除了表示实体内部结 ...
- 李洪强iOS开发之零基础学习iOS开发【02-C语言】03-关键字、标识符、注释
上一讲中已经创建了第一个C语言程序,知道了C程序是由函数构成的,这讲继续学习C语言的一些基本语法.C语言属于一门高级语言,其实,所有的高级语言的基本语法组成部分都是一样的,只是表现形式不太一样.就好像 ...
- [itint5]最短路径遍历点
http://www.itint5.com/oj/#50 此题有点难,参考了这篇文章,是个两条路的DP: http://blog.csdn.net/a83610312/article/details/ ...
- MyBatis Mapper 文件例子
转载:http://blog.csdn.net/ppby2002/article/details/20611737 <?xml version="1.0" encoding= ...
- Java Logger(java日志)
目录 1. 简介2. 安装3. log4j基本概念3.1. Logger3.2. Appender3.2.1. 使用ConsoleAppender3.2.2. 使用FileAppender3.2.3. ...