Qt关于tabWidget中tab样式的重绘

2023-11-03

Qt关于tabWidget中tab样式的重绘

版本说明

版本 作者 日期 备注
0.1 loon 2018.12.29 初稿

目录

一、需求分析

界面中需要做一个类似下面这样界面的效果:

在这里插入图片描述

在网上找了一下发现这篇文章:https://blog.csdn.net/skyztttt/article/details/52448992

OK,那么可以确定的就是这种效果可以通过QTabWidget来重绘达到类似的效果。只是对于参考文章中的内容部分内容不是很理解,直接套用后发现离我想要的效果还有些远,最终琢磨一段时间后发现要达到根据自己的要求重绘QTabWidget需要先了解Qt 2D绘图的一些基础概念,了解QPainter、QRect、QTextOption、QFont类、画刷和画笔等的作用(这些结合Qt助手和一些Qt教程书籍来学习和了解),以及对OOP中重写的一些了解(这个是语法问题了,暂时不会也不影响你照猫画虎)。

二、最终效果展示

在这里插入图片描述

三、源码详细说明

包含两部分,要重写肯定要有一个重写样式的类,然后tabwidget还要调用这个重写的类渲染样式。

重写类CustomTabStyle,继承自QProxyStyle,感兴趣的可以继续看看最终继承自哪里:

#ifndef CUSTOMTABSTYLE_H
#define CUSTOMTABSTYLE_H

#include <QPainter>
#include <QProxyStyle>


class CustomTabStyle:public QProxyStyle
{
public:
    CustomTabStyle();
    
    QSize sizeFromContents(ContentsType type, const QStyleOption *option,
            const QSize &size, const QWidget *widget) const;
    
    void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
};

#endif // CUSTOMTABSTYLE_H
#include "customtabstyle.h"
#include <QStyleOptionTab>

CustomTabStyle::CustomTabStyle()
{
    
}

QSize CustomTabStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
{
    QSize s = QProxyStyle::sizeFromContents(type, option, size, widget);
    if (type == QStyle::CT_TabBarTab) {
        s.transpose();
        s.rwidth() = 150; // 设置每个tabBar中item的大小
        s.rheight() = 40;
    }
    return s;
}

void CustomTabStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    if (element == CE_TabBarTabLabel) {
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
            QRect allRect = tab->rect;
            
            if (tab->state & QStyle::State_Selected) {  //选中状态:tab的Qlabel为矩形,底色为白色,边框淡灰色,文字为淡蓝色且加粗居中(具体颜色值由拾色器提取)
                painter->save();
                painter->setPen(0xdadbdc);  //设置画笔颜色为淡灰色
                painter->setBrush(QBrush(0xffffff));  //设置画刷为白色
                painter->drawRect(allRect.adjusted(0,0,0,0));  //重绘tab的矩形边框
                painter->restore();  //还原为默认
                
                painter->save();
                painter->setPen(0x006ab1);  //重新设置画笔颜色为淡蓝色
                QTextOption option;
                option.setAlignment(Qt::AlignCenter);  //设置文字居中
                painter->setFont(QFont("", 9, QFont::Bold));  //设置文字样式,大小为9并加粗,颜色由画笔决定
                painter->drawText(allRect, tab->text, option);  //重绘文字
                painter->restore();
            }
            else if(tab->state & QStyle::State_MouseOver) { //hover状态:tab的Qlabel为矩形,底色为灰色,边框仍未淡灰色,文字加粗居中
                painter->save();
                painter->setPen(0xdadbdc);  //设置画笔颜色为淡灰色
                painter->setBrush(QBrush(0xf2f2f2));  //设置画刷为灰色
                painter->drawRect(allRect.adjusted(0,0,0,0));  //重绘tab的矩形边框
                painter->restore();  //还原
                
                painter->save();
                QTextOption option;
                option.setAlignment(Qt::AlignCenter);  //设置文字居中
                painter->setFont(QFont("", 9, QFont::Bold));  //设置文字样式,大小为9并加粗,颜色由画笔决定
                painter->drawText(allRect, tab->text, option);  //重绘文字
                painter->restore();
            }
            else //其它的:tab的Qlabel为矩形,底色为灰色,边框为淡灰色不变,文字不加粗但居中
            {
                painter->save();
                painter->setPen(0xdadbdc);
                painter->setBrush(QBrush(0xf2f2f2));
                painter->drawRect(allRect.adjusted(0,0,0,0));
                painter->restore();
                
                painter->save();
                QTextOption option;
                option.setAlignment(Qt::AlignCenter);
                painter->drawText(allRect, tab->text, option);
                painter->restore();
            }
            
            return;
        }
    }
    
    if (element == CE_TabBarTab) {
        QProxyStyle::drawControl(element, option, painter, widget);
    }
}

调用,包含重写类的头文件然后按如下调用即可:

ui->tabWidget->tabBar()->setStyle(new CustomTabStyle);

四、最后

控件样式重绘其实就是对基类提供的样式方法进行重写(Overriding ),一般来说,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写,比如这里我们就不想用原来的样式,想自己重绘tabwidget中tab的样式。方法重写又称方法覆盖,这个概念一般是和重载一起出现的,具体更多的内容这里就不展开了。

面向对象编程中经常会遇到重写,它是多态性的一种体现。界面开发中经常会遇到控件样式重绘,因为默认系统自带的控件往往不符合我们的要求,无论是PC界面还是APP界面等的开发基本上都会遇到控件样式重绘,从原理上了解重写以及掌握一些重绘需要使用的类,那么灵活运用重绘就是迟早的事了。

再次感谢:https://blog.csdn.net/skyztttt/article/details/52448992
只有大家共同分享经验,才能让大家更快的进步。

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

Qt关于tabWidget中tab样式的重绘 的相关文章

  • Qt操作excel的三方库Qtxlsx在Windows下使用注意事项

    Qt操作excel的三方库Qtxlsx在Windows下使用注意事项 文章目录 Qt操作excel的三方库Qtxlsx在Windows下使用注意事项 1 Qt Xlsx简介 2 编译及添加模块 2 1 下载及编译 2 2 拷贝相关文件集成到
  • Qt源码分析之QObject

    在分析源码之前 我们先来介绍下Pimpl机制 Pimpl机制介绍 Pimpl private implementation 字面意思是私有实现 具体实现是将类的 假设类A 私有数据和函数放入一个单独的类 假设类Pimpl 中 然后在类A的头
  • QT学习 之 QwtPlot(数学绘图)

    QT对于统计图像 函数图像等的绘制是没有相关组件的帮助的 只有利用手工绘制图片 QwtPlot是用来绘制二维图像的widget 继承自QFrame 和 QwtPlotDict 不过严格的说来 它只是一个视图窗口 真正的绘制设备是它的中心部件
  • QT 5 中元对象系统的改变

    Qt 5 的元对象系统作出了一定的改变 既有底层变化 又有 API 的变化 其中有些修改与 Qt 4 不是源代码兼容的 本文将介绍这些改变 以及如何修改现有代码 使其能够使用 Qt 5 进行编译 同时 我们也将阐述下新增加的一些 API 使
  • Qt实现跨窗口信号槽通信

    多窗口通信 如果是窗口类对象之间互相包含 则可以直接开放public接口调用 不过 很多情况下主窗口和子窗口之间要做到异步消息通信 就必须依赖到跨窗口的信号槽 以下是一个简单的示例 母窗口 mainwindow h ifndef MAINW
  • Qt 主窗口与子窗口之间传值

    1 主函数向子函数传值 主窗口定义信号 子窗口定义槽函数 在主窗口将信号与槽连接起来 mainwindow h include
  • Qt中的QString与int、const char 、ASCII码互相转换

    1 QString 转 int bool ok QString str1 0xf8 int value1 str1 toInt ok 16 qDebug lt lt ok lt lt lt lt value1 true 248 QStrin
  • Ubuntu 配置第三方动态库的系统环境变量

    环境 ubuntu16 04 Qt5 7 1 简述 将第三方动态库配置到系统环境变量中 便于使用 步骤 1 将第三方动态库的头文件及 so 文件拷贝到桌面 RSAInclude文件夹 lib文件夹 2 进入桌面文件夹 打开命令框 3 输入命
  • 成为Qt开发大牛,从入门到精通,一步一步走完整个学习路线!

    简介 本文为 C QT 学习路线大纲 资料 文章底部 Qt 可以做什么 Qt 虽然经常被当做一个 GUI 库 用来开发图形界面应用程序 但这并不是 Qt 的全部 Qt 除了可以绘制漂亮的界面 包括控件 布局 交互 还包含很多其它功能 比如多
  • Qt:读写SVG

    Qt 读写SVG 绘制SVG图形 SvgView SvgView const QString file QWidget parent QWidget parent doc new QSvgRenderer file this QSvgRen
  • QT信号与槽的连接方式

    一 Qt AutoConnectionQt AutoConnection表示系统自动选择相应的连接方式 如果信号与槽在同一线程 就采用Qt DirectConnection 如果信号与槽不在同一线程 将采用Qt QueuedConnecti
  • Qt自定义类使用自定义含参信号与槽

    最近在自定义类中使用了信号来连接到MainWindow类中的槽函数 具体操作如下 要点一 继承QObject 在头文件中初始化自定义类MyThread1 这里由于继承的QThread已经继承了QObject 无需嵌套继承 故不必public
  • QT+PMAC联合开发

    最近接触到PMAC的IMAC FX控制器 虽然他的主程序是写在下位机 但还是需要上位机和它进行通信和交互 官方提供的上位机DEMO都是基于VC C 和VB等 对于QT的用户 没有很直接的代码供参考 PMAC提供了COM组件 供上位机调用 在
  • Qt 控制台运行无法弹出小黑框

    Qt Console Application Qt 主要是GUI界面的设计 但在学习的时候控制台运行显得更加方便一些 小编在第一次新建控制台运行的时候 点击运行没有弹出小黑框 解决方法 主要是因为没有执行qmake 就需要在Qt的pro文件
  • Qt Table 的表头合并

    最近接到了开发表格的需求 一般来说网上有很多不错的例子 表格的开发多半使用QtableWeiget或者Qtableview 为了美观 有很多样式设置的代码行 基本外观设置 FriendTable gt setFrameShape QFram
  • Qt - 检测windows系统休眠

    Windows Qt方案 场景 1 产品搭建在一体机上 需要关机缓存配置和用户操作信息 2 面对用户的关机 休眠设置 软件需要保留用户设置 方案 virtual protected bool QWidget nativeEvent cons
  • Qt进程间通信

    进程是操作系统的基础之一 一个进程可以认为是一个正在执行的程序 我们可以把进程当做计算机运行时的一个基础单位 关于进程的讨论已经超出了本章的范畴 现在我们假定你是了解这个概念的 在 Qt 中 我们使用 QProcess 来表示一个进程 这个
  • Qt QString字符串分割、截取的3种方法

    Qt QString字符串分割 截取 在做项目中不可避免的会使用到一串字符串中的一段字符 因此常常需要截取字符串 有两种方式可以解决这个问题 方法一 QString分割字符串 QString date dateEdit toString y
  • QT中日期和时间类

    QT中日期和时间类 QDate QTime QDateTime QDate QDate类可以封装日期信息也可以通过这个类得到日期相关的信息 包括 年 月 日 构造函数 QDate QDate QDate QDate int y int m
  • error: static assertion failed: Type is not registered, please use the Q_DECLARE_METATYPE macro to m

    error static assertion failed Type is not registered please use the Q DECLARE METATYPE macro to m 解决方案 报错信息如下 调用了类的静态函数导

随机推荐

  • PostMan学习记录10 - 上传文件

    后台代码示例 PostMapping upload public String upload RequestParam name files required false MultipartFile files try if files n
  • 目标检测系列:Faster RCNN、FPN

    Faster RCNN FPN Faster RCNN 动机 Fast RCNN虽然对于检测的速度已经接近于达到实时 但是候选区域的提取方法依然是依赖于传统的算法例如选择性搜索 而选择性搜索在CPU上要实现一张图像的候选区域提取需要达到2秒
  • 轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)

    轻量级Java EE企业应用实战 第4版 Struts 2 Spring4 Hibernate整合开发 含CD光盘1张 国家级奖项获奖作品升级版 四版累计印刷27次发行量超10万册的轻量级Java EE经典著作 李刚 编著 ISBN 978
  • 概率论【常见的五种分布】--猴博士爱讲课

    4 常见的五种分布 1 6 符合均匀分布 求概率 均匀分布U a b 2 6 符合泊松分布 求概率 泊松分布P A lambda是参数 x是某某次数 如果是这样的 千万不要用1 P X 6 这种 要一个一个算 3 6符合二项分布 求概率 4
  • 面试官,我已经掌握了MyBits,你看我还有机会吗?

    一 MyBatis 面试题 1 什么是 Mybatis 2 Mybaits 的优点 3 MyBatis 框架的缺点 4 MyBatis 框架适用场合 5 MyBatis 与 Hibernate 有哪些不同 6 和 的区别是什么 7 当实体类
  • Docker - 国内镜像的配置及使用

    开发十年 就只剩下这套Java开发体系了 gt gt gt Docker国内镜像 DaoCloud Docker加速器阿里云 开发者平台 微镜像 希云cSphere镜像广场 时速云灵雀云网易蜂巢 阿里云的Docker加速器 阿里云 开发者平
  • 对老赵写的简单性能计数器的修改

    对老赵写的简单性能计数器的修改 早上看到老赵写的这个性能计数器 感觉很实用 不过老赵用了很多 C 3 0 的新语法 还用了 VISTA 和 Server 2008 下特有的Win32 API 对于还在用C 2 0 或者还工作在 XP 或者
  • nginx启动只有master没有worker_探究Nginx的工作原理,才知道为什么这么高效!

    1 Nginx的模块 Nginx的模块从结构上分为核心模块 基础模块和第三方模块 核心模块 HTTP模块 EVENT模块和MAIL模块 基础模块 HTTP Access模块 HTTP FastCGI模块 HTTP Proxy模块和HTTP
  • 平面设计除了PS还有哪些工具推荐

    平面设计在我们的日常生活中无处不在 无论是传统媒体还是网络媒体 我们每天都会沉浸在大量的平面设计作品中 因此 我们或多或少会对设计有自己的看法 其实 即使是非专业人士 市场上也有很多平面设计软件 本文盘点了平面设计的五大软件 1 即时设计
  • Android 6.0 解决recyclerview 在 scrollview 中不能全部显示,高度不正常的问题。

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 这个问题困扰了我半天 国内百度上的资料非常的烂 根本无法解决问题 在android 4 5 版本中 scrollview 包含了一个recyclerview 滚动一切正常
  • 教你使用windeployqt工具来进行Qt的打包发布

    Qt 官方开发环境使用的动态链接库方式 在发布生成的exe程序时 需要复制一大堆 dll 如果自己去复制dll 很可能丢三落四 导致exe在别的电脑里无法正常运行 因此 Qt 官方开发环境里自带了一个工具 windeployqt exe 问
  • ARM64基础14:ARM64的中断处理之GIC400实现(以树莓派4采用的BCM2711芯片为例)

    接上篇 ARM64基础13 ARM64的异常处理之中断处理 以树莓派4采用的BCM2711芯片为例 1 GIC的诞生背景 传统中断控制器 比如树莓派4b的legacy interrupt controller 具备 中断enable寄存器
  • osgEarth+VS2015开发环境搭建

    前言 osgEarth是基于OpenSceneGraph OSG 实现的3DGIS引擎 而OSG是一个开源的三维实时场景图形开发框架 学习osgEarth之前最好先学习下OSG 这是OSG官网有很多学习资料可以参考 osgEarth同时支持
  • STM32CubeMX官网下载方法

    目录 CubeMX下载 芯片包下载 和CubeIDE区别 CubeMX下载 主要是对下载链接做个记录 不再从打开百度 搜索ST这样一步步记录 点击STM32CubeMX STM32Cube initialization code gener
  • 共识算法 PBFT浅析

    PBFT是PracticalByzantine Fault Tolerance的缩写 意为实用拜占庭容错算法 该算法是Miguel Castro 卡斯特罗 和Barbara Liskov 利斯科夫 在1999年提出来的 解决了原始拜占庭容错
  • 百度深度强化学习框架PARL技术学习笔记

    目录 前言 寄语 基础准备和预习 第一节课 玩个简单的迷宫游戏吧 第二节课 基于表格型方法求解RL 1 SARSA算法 2 Q Learning算法 第三节课 基于神经网络求解RL 第三节课 基于策略梯度求解RL 第四节课 连续动作空间上求
  • 前端开发工程师面试最常见问题(20题&附答案)

    目录 1 在制作一个Web应用或Web站点的过程中 你是如何考虑它的UI 安全性 高性能 SEO 可维护性以及技术因素的 2 谈谈你喜欢的开发环境 例如操作系统 编辑器 浏览器 工具等等 3 你最熟悉哪一套版本控制系统 4 描述一下当你制作
  • 全链接神经网络python简单实现

    什么是全链接神经网络 full connected FC 借用此图来直观的表示一下 规则如下 神经元按照层来布局 最左边的层叫做输入层 负责接收输入数据 最右边的层叫输出层 我们可以从这层获取神经网络输出数据 输入层和输出层之间的层叫做隐藏
  • linux新版本io框架 io_uring

    从别的博主那copy过来 1 io uring是Linux内核的一个新型I O事件通知机制 具有以下特点 高性能 相比传统的select poll epoll等I O多路复用机制 io uring采用了更高效的ring buffer实现方式
  • Qt关于tabWidget中tab样式的重绘

    Qt关于tabWidget中tab样式的重绘 版本说明 版本 作者 日期 备注 0 1 loon 2018 12 29 初稿 目录 文章目录 Qt关于tabWidget中tab样式的重绘 版本说明 目录 一 需求分析 二 最终效果展示 三