QTableView数据列表添加复选框利用自定义委托

0 453
索鸟 2021-03-22
需要:0索币

之前就遇到表格里内嵌复选框的问题,网上查了好多资料也没有完全解决,今天花时间研究和实验后基本搞定。

使用的是自定义委托的方式,重写了panit函数和editorEvent函数实现指定列内嵌复选框,单击实现选中状态切换、选中状态下按空格键也可改变选中状态以及改变单元格大小时复选框始终在中间。


主要思路:paint函数里进行复选框的绘制,并实时读取模型数据显示状态,editorEvent函数里判断单元格点击情况进行处理。


源代码如下:


checkdelegate.h

#ifndef CHECKDELEGATE_H

#define CHECKDELEGATE_H

 

#include <QStyledItemDelegate>

#include <QtGui>

 

class CheckBoxDelegate : public QStyledItemDelegate

{

    Q_OBJECT

public:

    CheckBoxDelegate(QObject *parent = 0);

protected:

    void paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index) const;

    bool editorEvent(QEvent *event,QAbstractItemModel *model,const QStyleOptionViewItem &option,const QModelIndex &index);

};

 

 

#endif // CHECKDELEGATE_H


checkdelegate.cpp

#include "checkdelegate.h"

#include <QMouseEvent>

#include <QPainter>

#include <QStyleOption>

 

static QRect CheckBoxRect(const QStyleOptionViewItem &viewItemStyleOptions)/*const*/

{

    //绘制按钮所需要的参数

    QStyleOptionButton checkBoxStyleOption;

    //按照给定的风格参数 返回元素子区域

    QRect checkBoxRect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);

    //返回QCheckBox坐标

    QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + viewItemStyleOptions.rect.width() / 2 - checkBoxRect.width() / 2,

                         viewItemStyleOptions.rect.y() + viewItemStyleOptions.rect.height() / 2 - checkBoxRect.height() / 2);

    //返回QCheckBox几何形状

    return QRect(checkBoxPoint, checkBoxRect.size());

}

 

CheckBoxDelegate::CheckBoxDelegate(QObject *parent):

    QStyledItemDelegate(parent)

{

 

}

 

void CheckBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const

{

    bool checked = index.model()->data(index, Qt::DisplayRole).toBool();

 

    if(index.column() == 0){

        qDebug() << checked;

        QStyleOptionButton checkBoxStyleOption;

        checkBoxStyleOption.state |= QStyle::State_Enabled;

        checkBoxStyleOption.state |= checked? QStyle::State_On : QStyle::State_Off;

        checkBoxStyleOption.rect = CheckBoxRect(option);

 

        QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxStyleOption,painter);

    }else{

        QStyledItemDelegate::paint(painter, option, index);

    }

}

 

bool CheckBoxDelegate::editorEvent(QEvent *event,

                                QAbstractItemModel *model,

                                const QStyleOptionViewItem &option,

                                const QModelIndex &index) {

    if(index.column() == 0){

    if((event->type() == QEvent::MouseButtonRelease) ||

            (event->type() == QEvent::MouseButtonDblClick)){

        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);

        if(mouseEvent->button() != Qt::LeftButton ||

                !CheckBoxRect(option).contains(mouseEvent->pos())){

            return true;

        }

        if(event->type() == QEvent::MouseButtonDblClick){

            return true;

        }

    }else if(event->type() == QEvent::KeyPress){

        if(static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space &&

                static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select){

            return false;

        }

    }else{

        return false;

    }

 

    bool checked = index.model()->data(index, Qt::DisplayRole).toBool();

    return model->setData(index, !checked, Qt::EditRole);

    }else{

        return QStyledItemDelegate::editorEvent(event, model, option, index);

    }

}


引用代码:

#include <QtGui/QApplication>

#include "checkdelegate.h"

#include <QtGui>

 

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    QTableView tb;

    QStandardItemModel *md = new QStandardItemModel(/*&tb*/);

    md->setRowCount(5);

    md->setColumnCount(5);

    for(int i = 0;i<4;i++){

        md->setData(md->index(1,i+1),QString("1"),Qt::EditRole);

    }

    CheckBoxDelegate *ck = new CheckBoxDelegate(/*&tb*/);

 

    tb.setModel(md);

    tb.setItemDelegate(ck);

    tb.show();

 

    return a.exec();

}



效果图:

原文链接:https://blog.csdn.net/u013399898/article/details/52579596

回帖
  • 消灭零回复
相关主题
2020年最新最新Kubernetes视频教程(K8s)教程 2
程序员转型之制作网课变现,月入过万告别996 1
索鸟快传2.0发布啦 1
两个不同网络的电脑怎么实现文件的互相访问呢? 1
网盘多账号登录软件 1
Java实战闲云旅游项目基于vue+element-ui 1
单点登录技术解决方案基于OAuth2.0的网关鉴权RSA算法生成令牌 1
QT5获取剪贴板上文本信息QT设置剪贴板内容 1
springboot2实战在线购物系统电商系统 1
python web实战之爱家租房项目 1
windows COM实用入门教程 1
C++游戏开发之C++实现的水果忍者游戏 1
计算机视觉库opencv教程 1
node.js实战图书管理系统express框架实现 1
C++实战教程之远程桌面远程控制实战 1
相关主题
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0