Qt之QTableView添加复选框(QAbstractTableModel)
简述
使用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)
{
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:
{
if (nColumn == CHECK_BOX_COLUMN)
{
record.bChecked = (value.toInt() == Qt::Checked);
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::CheckStateRole:
{
if (nColumn == CHECK_BOX_COLUMN)
return record.bChecked ? Qt::Checked : Qt::Unchecked;
}
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;
if (index.column() == CHECK_BOX_COLUMN)
flags |= Qt::ItemIsUserCheckable;
return flags;
}
接口说明
updateData
主要用于更新数据,刷新界面。data
用来显示数据,根据角色(颜色、文本、对齐方式、选中状态等)判断需要显示的内容。setData
用来设置数据,根据角色(颜色、文本、对齐方式、选中状态等)判断需要设置的内容。headerData
用来显示水平/垂直表头的数据。flags
用来设置单元格的标志(可用、可选中、可复选等)。
样式
QSS不仅可以设置表格、表格项样式(背景、文本等),也可以通过indicator来设置复选框的样式:
QTableView {
border: 1px solid rgb(50, 50, 50);
background: rgb(57, 58, 60);
gridline-color: rgb(60, 60, 60);
}
QTableView::item {
border: none;
border-bottom: 1px solid rgb(50, 50, 50);
}
QTableView::item:selected {
background: rgb(0, 160, 230);
}
QTableView::indicator {
width: 17px;
height: 17px;
}
QTableView::indicator:enabled:unchecked {
image: url(:/Images/checkBox);
}
QTableView::indicator:enabled:unchecked:hover {
image: url(:/Images/checkBoxHover);
}
QTableView::indicator:enabled:unchecked:pressed {
image: url(:/Images/checkBoxPressed);
}
QTableView::indicator:enabled:checked {
image: url(:/Images/checkBoxChecked);
}
QTableView::indicator:enabled:checked:hover {
image: url(:/Images/checkBoxCheckedHover);
}
QTableView::indicator:enabled:checked:pressed {
image: url(:/Images/checkBoxCheckedPressed);
}
QTableView::indicator:enabled:indeterminate {
image: url(:/Images/checkBoxIndeterminate);
}
QTableView::indicator:enabled:indeterminate:hover {
image: url(:/Images/checkBoxIndeterminateHover);
}
QTableView::indicator:enabled:indeterminate:pressed {
image: url(:/Images/checkBoxIndeterminatePressed);
}
使用
QTableView *pTableView = new QTableView(this);
TableModel *pModel = new TableModel(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);
// 加载数据、更新界面
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添加复选框(QAbstractTableModel)的更多相关文章
- Qt之QTableView添加复选框(QAbstractItemDelegate)
简述 上节分享了使用自定义模型QAbstractTableModel来实现复选框.下面我们来介绍另外一种方式: 自定义委托-QAbstractItemDelegate. 简述 效果 QAbstract ...
- 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 ...
随机推荐
- ios状态栏调整 简单动画的知识点
首先状态栏式view的属性,所以在viewController中直接重写: /** 修改状态栏 */ - (UIStatusBarStyle)preferredStatusBarStyle { // ...
- Consumer closed input channel or an error occurred. events=0x8 channel is unrecoverably broken and will be disposed(待解决)
跟文件读取有关?关闭文件读取试试. 有可能是读取文件 出现报错
- java 伪静态的方法
1.jar包支持urlrewritefilter-4.0.3.jar http://files.cnblogs.com/simpledev/urlrewritefilter-4.0.3.rar 2. ...
- C++中的const关键字
http://blog.csdn.net/eric_jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方 ...
- Chp17: Moderate
17.1 swap a number in place.(without temporary variables) a = a ^ b; b = a ^ b; a = a ^ b; 17.3 Writ ...
- JS 变量或参数是否有值的判断
var node; …… 判断 node 是否有值,是否为 undefine,是否 null,直接使用两个!!,否定之否定: if (!!node){ .... }else{ .... } 这个条件判 ...
- Javascript中appendChilid()内涵
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- Android 一个Activity保存它自己的实例
一个Activity保存他自己的实例的作用是,在其他Activity中可以方便的调用该Activity里的方法. 我们可以使用一个静态的变量保存当前Activity的实例,并将其标志为private访 ...
- lintcode:两个数的和
题目 两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是1到n,不 ...
- 安装xampp后,出现“Apache 2 Test Page powered by CentOS“
因为是在本地测试,所以没有去考虑为什么会这样,考虑太多的原因.只要能运行就行. 所以网络搜索了一番. 最后,解决办法是: 1, 找到apachectl. 那么就在命令行敲find / -name ap ...