Qt自定义Delegate实现QTableWidget整行选中圆角矩形高亮效果

2023-11-13

问题背景

参照一个现有的Linux桌面应用,尽可能的模仿它的UI,其中有一个UI效果就是列表整行选中后是一个圆角矩形高亮效果,如下图所示。
在这里插入图片描述

参考代码

先放代码,实现的思路就是用代理来重绘我们想要的效果。

#include <QStyledItemDelegate>
class MyDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    MyDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;

private:
    void paintBackground(QPainter *painter, const QRect &rect, const int &column, const QBrush &brush) const;
    void paintBackgroundBase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void paintBackgroundAlternateBase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void paintBackgroundHighLighted(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    void paintForegroundText(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    if (option.state & QStyle::State_Selected)
    {
        paintBackgroundHighLighted(painter, option, index);
    }
    else if ( index.row() % 2 == 0)
    {
        paintBackgroundBase(painter, option, index);
    }
    else
    {
        paintBackgroundAlternateBase(painter, option, index);
    }

    paintForegroundText(painter, option, index);
}

void MyDelegate::paintBackgroundHighLighted(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    paintBackground(painter, option.rect, index.column(), option.palette.highlight());
}

void MyDelegate::paintBackgroundBase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    paintBackground(painter, option.rect, index.column(), option.palette.base());
}

void MyDelegate::paintBackgroundAlternateBase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    paintBackground(painter, option.rect, index.column(), option.palette.alternateBase());
}

void MyDelegate::paintBackground(QPainter *painter, const QRect &rect, const int &column, const QBrush &brush) const
{
    int width = rect.width();
    if ( column == 0 /*option.viewItemPosition == QStyleOptionViewItem::Beginning*/)
    {
        QPainterPath path;
        path.setFillRule(Qt::WindingFill);
        path.addRoundedRect(rect, 8, 8);
        path.addRect(QRect(rect.x() + width / 2, rect.y(), width / 2, rect.height()));
        painter->fillPath(path, brush);
    }
    else if ( column == 2/*option.viewItemPosition == QStyleOptionViewItem::End*/)
    {
        QPainterPath path;
        path.setFillRule(Qt::WindingFill);
        path.addRoundedRect(rect, 8, 8);
        path.addRect(QRect(rect.x(), rect.y(), width / 2, rect.height()));
        painter->fillPath(path, brush);
    }
    else
    {
         painter->fillRect(rect, brush);
    }
}

void MyDelegate::paintForegroundText(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QFontMetrics fontMetrics(painter->font());
    QString msg = fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, option.rect.width());
    QApplication::style()->drawItemText(painter, option.rect, option.displayAlignment, QApplication::palette(), true, msg);
}

代码讲解

推荐继承自QStyledItemDelegate,因为它可以使用当前的Sytle绘制Items,而继承QItemDelegate需要自定义Sytle。具体可以参考Qt的手册 QStyledItemDelegate vs. QItemDelegate,讲解的比较详细。

QStyledItemDelegate vs. QItemDelegate
Since Qt 4.4, there are two delegate classes: QItemDelegate and QStyledItemDelegate. However, the default delegate is QStyledItemDelegate. These two classes are independent alternatives to painting and providing editors for items in views. The difference between them is that QStyledItemDelegate uses the current style to paint its items. We therefore recommend using QStyledItemDelegate as the base class when implementing custom delegates or when working with Qt style sheets. The code required for either class should be equal unless the custom delegate needs to use the style for drawing. If you wish to customize the painting of item views, you should implement a custom style. Please see the QStyle class documentation for details.

Qt没有部分绘制圆角,部分绘制直角矩形的接口,所以实现上述效果有两个思路:

  1. 从点线开始,完全重绘一个满足我们要求的矩形;
  2. 将圆角矩形和直角矩形部分重叠,从而实现一半是圆角,一半是直角的矩形。

采用第二种办法,代码如下,需要注意的是填充效果需要是Qt::WindingFill

QPainterPath path;
path.setFillRule(Qt::WindingFill); /* 填充效果 */
path.addRoundedRect(rect, 8, 8);
path.addRect(QRect(rect.x() + width / 2, rect.y(), width / 2, rect.height()));
painter->fillPath(path, brush);

如果表格中的文字太长的话,人性化的效果是被遮挡的部分用省略号表示出来,代码如下所示。继承自QStyledItemDelegate后,我们就不用关心这行文字的效果是高亮选中的,还是普通效果,直接丢给接口即可。

void MyDelegate::paintForegroundText(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QFontMetrics fontMetrics(painter->font());
    QString msg = fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, option.rect.width());
    QApplication::style()->drawItemText(painter, option.rect, option.displayAlignment, QApplication::palette(), true, msg);
}

推荐使用表格背景交替的显示效果,并且未选中高亮的背景也是圆角矩形显示。提取出两个接口

    void paintBackgroundBase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void paintBackgroundAlternateBase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt自定义Delegate实现QTableWidget整行选中圆角矩形高亮效果 的相关文章

  • 网站报错 :SLQSTATE[HY000]:General error:145 Table ‘./**@002******@/002ecn/ey_config‘ is mar

    后台使用过程中 因为某个操作而出现报错 SQLSTATE HY000 General error 145 Table 002 002ecn ey config is marked as crashed and should be repai
  • 《Linux运维实战:Centos7.6一键离线部署docker19.03.9》

    文章目录 一 部署背景 三 部署工具 三 部署演示 总结 整理不易 如果对你有帮助 可否点赞关注一下 一 部署背景 由于业务系统的特殊性 我们需要面向不通的客户安装我们的业务系统 而作为基础组件中的docker针对不同的客户环境需要多次部署
  • 通过docker搭建skywalking

    简述 这里引用skywalking官方网站上简介 分布式系统的应用程序性能监视工具 专为微服务 云原生架构和基于容器 Docker K8s Mesos 架构而设计 SkyWalking 是观察性分析平台和应用性能管理系统 提供分布式追踪 服
  • IPO 后,北森不断超越自身

    北森锐意变革的思路值得很多行业借鉴 数科星球原创 作者丨苑晶 编辑丨大兔 在所有 HR SaaS 软件中 北森较为独特 这种独特不光体现在其切入赛道的一体化产品 也体现在它所走过的发展路径 2023 年年中 当人口红利消逝之际 人们对人力资
  • 面试题_Java源文件中可以有多个类,为什么只能有一个public类?

    Java中源文件中可以有多个类 最多只能有一个public类 如果源文件中有多个类 那么只能有一个类是public类 如果有一个类是public类 那么源文件的名字必须和这个类的名字完全相同 扩展名为 java java程序的入口是main
  • 计算机网络——数据链路层の选择题整理

    数据链路层的功能 1 数据链路层协议的功能不包括 A 定义数据格式 B 提供结点之间的可靠传输 C 控制对物理传输介质的访问 D 为终端结点隐蔽物理传输的细节 解析 选D 对于A 定义数据格式 即采用帧作为传输单元 对于B 提供结点之间的可
  • 安卓开发之前端

    安卓开发之前端界面的搭建 前段时间因为网络编程这门课要做一个课程project 题目是本地服务器的开发 需要开发一个安卓客户端 于是就把去年小学期学的那点安卓知识捡起来了 心累 想到去年小学期学的那点安卓真的不算什么 就是一些很简单的东西
  • windgb调试

    reference http hi baidu com lewutian blog item 191047882b9c399fa5c27261 html 调试前的必备工作 在开始调试前首先要做的工作是设置好符号 Symbols 路径 没有符
  • C++constexpr函数(常量表达式函数)

    1 语法 在定义函数时用constexpr关键字作为前缀修饰函数 如 constexpr int fun return 20 注意 定义了一个constexpr函数后 函数声明也要加上constexpr关键字 constexpr函数只能有一
  • 如何安装svelte_在Svelte JS中使用环境变量

    如何安装svelte Process is not defined the compiler just slapped you in the face again You are tempted to hardcode your envir
  • 使用 PyTorch C++ 前端

    PyTorch C 前端是 PyTorch 机器学习框架的纯 C 接口 虽然 PyTorch 的主要接口是 Python 但 Python API 位于大量 C 代码库之上 提供基础数据结构和功能 例如张量和自动微分 C 前端公开了一个纯
  • linux查看系统中文件的内存占用以及具体某个文件夹下内存占用

    1 linux查看系统文件内存占用 df hl 2 Linux查看某个具体文件夹下文件的内存占用 du sh
  • SpringCloud——网关Gateway

    文章目录 六 统一网关 Gateway 6 1 网关介绍 6 2 快速搭建网关 6 3 断言工厂 6 4 过滤器工厂 6 5 全局过滤器 GlobalFIlter 6 6 过滤器的执行顺序 6 7 跨域问题 六 统一网关 Gateway 6
  • C编写的程序可能产生的主要缺陷

    摘自 软件静态分析工具评析 王 凯 孔祥营 空指针引用 悬空指针 资源泄露 函数返回值 使用未初始化变量 无限循环 死亡代码 缓冲区溢出 野指针等 1 空指针引用 空指针引用会导致程序崩溃 空指针引用的情况包括 忘记对指针为NULL 的情况
  • java入门四:数组

    1 数组概述 数组是最简单的数据结构 是相同类型数据的有序集合 数组描述的是相同类型的若干个数据 按照一定的先后次序排列组合而成的 数组中 每一个数据称作一个数组元素 每个数组元素可以通过一个下标来访问他们 2 数组的声明创建 首先必须声明
  • 分享解决jar包冲突问题的方法:(看了这个你就能解决所有包冲突问题!)

    1 问题描述 maven eclipse环境 1 1 昨晚发布这个新功能 接入notify消息中间件 预发失败 报 nested exception is java lang NoSuchMethodError org springfram
  • Go函数--匿名函数与闭包

    0 匿名函数概念 Go语言提供两种函数 有名函数和匿名函数 所谓匿名函数就是没有函数名的函数 匿名函数没有函数名 只有函数体 它和有名函数的最大区别是 我们可以在函数内部定义匿名函数 形成类似嵌套的效果 匿名函数常用于实现回调函数 闭包等
  • is服务器虚拟目录,Tomcat虚拟目录配置

    1 编辑server文件 x tomcat conf server xml 2 只要在server xml文件中加入如下代码即可 注意 在server xml中 此语句 unpackWARs true autoDeploy true xml

随机推荐

  • 数据库:sql 递归

    mysql 自关联表 以下为向下递归以及向上递归样例 1 递归查询前期准备 如果你的表已经存在 可忽略此步 建表 CREATE TABLE wq areainfo id int 11 NOT null AUTO INCREMENT leve
  • 服务器A拷贝文件到服务器B

    命令格式如下 scp 要拷贝的文件名 服务器B的用户名 IP 服务器B要存放的路径 拷贝文件 如 scp install log root 192 168 33 111 home 或 scp install log 192 168 33 1
  • Docker是什么?

    一 概述 Docker是一个用于开发 交付和运行应用程序的开放平台 Docker使您能够将应用程序与基础架构分离 从而实现快速交付软件 借助Docker 您可以以与管理应用程序相同的方式来管理基础架构 通过利用Docker快速交付 测试和部
  • python生成微信个性签名的词云图

    需要用到的库 itchat jieba numpy wordcloud import itchat import re import jieba import matplotlib pyplot as plt import PIL Imag
  • 企业运维

    欢迎关注 全栈工程师修炼指南 公众号 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 专注 企业运维实践 网络安全 系统运维 应用开发 物联网实战 全栈文章 等知识分享 花开堪折直须折 莫待无花空折枝 作者主页 https w
  • QT控件之(QLabel)中加载了图片想清除掉

    这个时候直接在你加载图片的那个label中使用如下代码 清除label中加载过来的图片 label clear qt学习推荐 百度云盘 链接 https pan baidu com s 11b634VvKMIsGdahyBLpZ3Q 提取码
  • 远程调试Android/IOS设备/微信网页方法汇总

    以下汇总现在可远程调试手机网页的几个方法 基本上官方都有详细的说明文档 可移步至相关网站查看 这里就不赘述使用 操作方法了 微信web开发者工具 PC客户端 官方说明文档 支持Windows和Mac系统 支持调试Android和IOS设备
  • 原生 fetch 请求 fetch和ajax的区别

    比如请求一个json文件 async function 请求 let res fetch data1 json 解析内容 let data await res json 获取到json 文件 console log data 比如请求一个图
  • NG4+NG-ZORRO搭建项目

    一 安装Nodejs Angular CLI 安装nodejs node官网下载安装即可 安装完成后查看版本信息 npm v npm install g angular cli 下载Angular CLI 查看Angular CLI的安装结
  • 【正点原子STM32连载】第四十二章 FLASH模拟EEPROM实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1 实验平台 正点原子MiniPro H750开发板 2 平台购买地址 https detail tmall com item htm id 677017430560 3 全套实验源码 手册 视频下载地址 http www openedv
  • 使用Encoder-Decoder模型自动生成对联的思路

    版权声明 可以任意转载 转载时请标明文章原始出处和作者信息 author 张俊林 在我看到第一篇Encoder Decoder模型的论文的时候 我就觉得用这个来作对联自动生成是再合适不过的了 做诗词应该也是比较适合的 但是相对诗词 用它来做
  • Linux wget下载指定目录及重命名

    Linux系统wget下载指定目录及重命名 假设目录为 happy page 假设下载网址为 http www baidu com 假设下载文件的原始文件名为 baidu html 1 指定下载目录 wget P happy page ht
  • PCL-获取点云体素中的所有点的索引的方法

    使用 octree 将点云体素化之后 获取体素中所有点的方法 即OctreeContainerBase中的三个方法的介绍 getPointIndex getPointIndicesVector getPointIndices 这三个方法都是
  • R语言tidyr包的详解

    tidyr用于数据处理 可以实现数据长格式和宽格式之间的相互转换 这里所指的长格式数据就是一个观测对象由多行组成 而宽数据格式则是一个观测仅由一行组成 除此之外 tidyr还可以对数据进行拆分和合并 同时也能够对缺失值进行简单的处理 tid
  • oracle(内置函数)

    1 转换函数 to char to number to date 例子 to number 转成数值型 select to number 22 23 from dual 2 to char 转成字符型 select to char 22 哈
  • Criss-Cross Attention for Semantic Segmentation论文及代码分析

    先附上论文及代码 该工作于2019年发表于ICCV会议 1 Introduction 由于固定的几何结构 传统的FCN受限于局部的感受野 只能提供短程的上下文信息 这对于提升分割任务的精度起到相反的影响 为了弥补FCN的缺陷 ASPP和PP
  • JAVA环境变量的配置及常用工具说明

    首先 到官网www eclipse com下载并安装最新版本的JDK 其次 找到设置位置 我的电脑 右键 属性 高级系统设置 高级 默认 环境变量 系统变量 新建系统变量JAVA HOME和CLASSPATH 变量名 JAVA HOME 变
  • 汉诺塔问题(C语言)

    汉诺塔问题 文章目录 汉诺塔问题 汉诺塔是什么 一 怎么解决汉诺塔问题 1 1 操作规则 1 2 函数递归 递归的两个必要条件 例题 斐波那契数列 二 解题步骤 2 1 代码如下 示例 2 2 图解 2 n 1 在这里插入图片描述 2 3
  • 微信小程序上线发布流程

    最近花了一天左右的时间学习了下微信小程序的开发 试着练习一把的心态 搞了一个很简单的页面 就当是学习总结吧 学习要点还是挺多的 通过查看官方接口文档 熟悉微信小程序开发工具 工程架构 相比传统页面开发类似 微信小程序也是由js文件 页面布局
  • Qt自定义Delegate实现QTableWidget整行选中圆角矩形高亮效果

    问题背景 参照一个现有的Linux桌面应用 尽可能的模仿它的UI 其中有一个UI效果就是列表整行选中后是一个圆角矩形高亮效果 如下图所示 参考代码 先放代码 实现的思路就是用代理来重绘我们想要的效果 include