Qt滑动条美化自定义

news2024/12/28 5:40:39

效果展示

主要代码

头文件

下面是hi控件的头文件,我们继承一个Qt原生的滑动条类QSlider,然后在基类的基础上进行自定义,我会对重要的变量进行解析:

class XSlider : public QSlider
{
    Q_OBJECT
public:
    explicit XSlider(QWidget* parent = nullptr);

protected:
    void paintEvent(QPaintEvent *ev) override;
    void mousePressEvent(QMouseEvent* ev) override;

private:
    int sliderHeight;
    QColor normalColor;
    QColor grooveColor;
    QColor handleBorderColor;
    QColor handleColor;
    QColor textColor;

private slots:
    void initForm();
    void initStyle();

public:
    int getSliderHeight();
    QColor getNormalColor();
    QColor getGrooveColor();
    QColor getHandleBorderColor();
    QColor getHandleColor();
    QColor getTextColor();

private:
    void setSliderHeight(int& sliderHeight);
    void setNormalColor(QColor& normalColor);
    void setGrooveColor(QColor& grooveColor);
    void setHandleBorderColor(QColor& handleBorderColor);
    void setHandleColor(QColor& handleColor);
    void setTextColor(QColor& textColor);

Q_SIGNALS:
    void clicked();
};
  • Q_OBJECT:让类支持信号和槽
  • normalColor:没有覆盖部分的颜色
  • grooveColor:覆盖之后的颜色
  • handleBorderColor:手柄的边框颜色
  • handleColor:手柄的颜色

绘制事件 QPaintEvent

void XSlider::paintEvent(QPaintEvent *ev)
{
    // 绘制父类
    QSlider::paintEvent(ev);

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);

    QStyleOptionSlider opt;
    initStyleOption(&opt);
    QRect rect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);

    int x = rect.x();
    int y = rect.y();
    int width = rect.width();
    int height = rect.height();
    if (width < height) {
        width = height;
    }
    else {
        height = width;
    }

    QFont font;
    font.setPixelSize(width / 2);
    painter.setFont(font);
    painter.drawText(x, y, width, height, Qt::AlignCenter, QString::number(value()));
}

这段代码是一个自定义的Qt滑块控件XSliderpaintEvent函数实现。在这个函数中,滑块的绘制过程改为我们自定义的滑块,具体逻辑如下:

  1. 调用父类绘制: 使用QSlider::paintEvent(ev);来确保滑块的基本绘制功能得到执行。
  2. 创建画家对象: QPainter painter(this);创建一个绘图对象,允许在当前控件上进行绘制。
  3. 设置抗锯齿: painter.setRenderHints(QPainter::Antialiasing);启用抗锯齿,使得绘制的文本和形状更加平滑。
  4. 初始化样式选项: initStyleOption(&opt);用于获取当前滑块的样式选项,这些选项会影响后续的绘制。
  5. 获取滑块句柄矩形区域:
QRect rect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);

通过样式获取滑块句柄的位置和大小。

  1. 确定宽高一致性: 根据矩形的宽度和高度,确保它们一致。如果宽度小于高度,就将宽度设置为高度;反之亦然。这保证了文本在正方形区域内居中显示。
  2. 设置字体大小:
QFont font;
font.setPixelSize(width / 2);
painter.setFont(font);

设置字体大小为矩形宽度的一半,以便在控件中适当显示数值。

  1. 绘制文本:
painter.drawText(x, y, width, height, Qt::AlignCenter, QString::number(value()));

将当前滑块值以文本形式居中绘制到之前计算出的矩形区域内。

初始化

  • 颜色初始化,没有什么好说的,只是要记得初始化一个好看的配色:
void XSlider::initForm()
{
    sliderHeight = 18;
    normalColor = QColor("#A0D7DA");
    grooveColor = QColor("#22A3A9");
    handleBorderColor = QColor("#0E99A0");
    handleColor = QColor("#FFFFFF");
    textColor = QColor("#000000");

    this->setOrientation(Qt::Horizontal);
}
  • 样式表初始化,这个很重要,是自定义的滑动条是否好看的决定性因素:
void XSlider::initStyle()
{
    int sliderRadius = sliderHeight / 2;
    int handleSize = (sliderHeight * 3) / 2 + (sliderHeight / 5);
    int handleRadius = handleSize / 2;
    int handleOffset = handleRadius / 2;

    QStringList list;
    int handleWidth = handleSize + sliderHeight / 5 - 1;
    list.append(QString("QSlider::horizontal{min-height:%1px;color:%2;}").arg(sliderHeight * 2).arg(textColor.name()));
    list.append(QString("QSlider::groove:horizontal{background:%1;height:%2px;border-radius:%3px;}")
                .arg(normalColor.name()).arg(sliderHeight).arg(sliderRadius));
    list.append(QString("QSlider::add-page:horizontal{background:%1;height:%2px;border-radius:%3px;}")
                .arg(normalColor.name()).arg(sliderHeight).arg(sliderRadius));
    list.append(QString("QSlider::sub-page:horizontal{background:%1;height:%2px;border-radius:%3px;}")
                .arg(grooveColor.name()).arg(sliderHeight).arg(sliderRadius));
    list.append(QString("QSlider::handle:horizontal{width:%3px;margin-top:-%4px;margin-bottom:-%4px;border-radius:%5px;"
                        "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.8 %1,stop:0.9 %2);}")
                .arg(handleColor.name()).arg(handleBorderColor.name()).arg(handleWidth).arg(handleOffset).arg(handleRadius));

    //偏移一个像素
    handleWidth = handleSize + sliderHeight / 5;
    list.append(QString("QSlider::vertical{min-width:%1px;color:%2;}").arg(sliderHeight * 2).arg(textColor.name()));
    list.append(QString("QSlider::groove:vertical{background:%1;width:%2px;border-radius:%3px;}")
                .arg(normalColor.name()).arg(sliderHeight).arg(sliderRadius));
    list.append(QString("QSlider::add-page:vertical{background:%1;width:%2px;border-radius:%3px;}")
                .arg(grooveColor.name()).arg(sliderHeight).arg(sliderRadius));
    list.append(QString("QSlider::sub-page:vertical{background:%1;width:%2px;border-radius:%3px;}")
                .arg(normalColor.name()).arg(sliderHeight).arg(sliderRadius));
    list.append(QString("QSlider::handle:vertical{height:%3px;margin-left:-%4px;margin-right:-%4px;border-radius:%5px;"
                        "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.8 %1,stop:0.9 %2);}")
                .arg(handleColor.name()).arg(handleBorderColor.name()).arg(handleWidth).arg(handleOffset).arg(handleRadius));


    QString qss = list.join("");
    this->setStyleSheet(qss);
}

这段代码是XSlider类的initStyle()函数实现,用于初始化和设置滑块控件的样式。通过使用Qt样式表(QSS),可以自定义滑块的外观。下面对代码进行详细解释:

主要步骤解析

  1. 计算尺寸参数:
    • sliderRadius: 计算滑块轨道的半径,通常为滑块高度的一半。
    • handleSize: 定义滑块手柄的大小,根据滑块高度计算得到。
    • handleRadius: 手柄半径,为手柄尺寸的一半。
    • handleOffset: 手柄偏移量,便于后续位置调整。
  2. 创建样式列表:
    使用QStringList list;来存储不同状态下的样式字符串。
  3. 添加水平样式:
list.append(QString("QSlider::horizontal{min-height:%1px;color:%2;}").arg(sliderHeight * 2).arg(textColor.name()));
- 定义了水平方向上滑块的最小高度及文本颜色。
  1. 绘制轨道、增加和减少页面背景:
list.append(QString("QSlider::groove:horizontal{background:%1;height:%2px;border-radius:%3px;}")
            .arg(normalColor.name()).arg(sliderHeight).arg(sliderRadius));
- 自定义了轨道(groove)、增加页面(add-page)和减少页面(sub-page)的背景色、高度以及边角圆弧。
  1. 自定义手柄样式:
 list.append(QString("QSlider::handle:horizontal{width:%3px;margin-top:-%4px;margin-bottom:-%4px;border-radius:%5px;"
                     "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.8 %1,stop:0.9 %2);}")
             .arg(handleColor.name()).arg(handleBorderColor.name()).arg(handleWidth).arg(handleOffset).arg(handleRadius));
- 为水平手柄设置宽度、边距、圆角,并应用径向渐变作为背景,使其外观更具层次感。
  1. 处理垂直方向样式:
    类似于水平方向,对垂直方向上的控件也进行了相应的样式设定,包括最小宽度、轨道颜色以及手柄等。这一部分代码与水平部分逻辑相似,但根据垂直方向调整了参数,如宽度和高度等。
  2. 应用样式表:
    最后,将所有收集到的QSS规则通过以下方式应用到当前控件:
QString qss = list.join("");
this->setStyleSheet(qss);

开源地址

http://gitea.huangyanjie.com/lennlouis/qtextendwidget
如果克隆失败请再试一次,或者直接选择下载。

参考资料:https://it.0voice.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wordpress实用功能A5资源网同款 隐藏下载框 支付框 需要登录才能查看隐藏的内容

实用功能 隐藏下载框 支付框 需要登录才能查看隐藏的内容, 个人网站防天朝申查实测有效 。 登录前&#xff0c;未登录&#xff1a; 登录后&#xff0c;已登录&#xff1a; 功能说明 该代码段的主要功能是隐藏支付框并为未 登录用户显示一条提示信息&#xff0c;告知他们需要…

Vue 简单入手

前端工程化&#xff08;Front-end Engineering&#xff09;指的是在前端开发中&#xff0c;通过一系列工具、流程和规范的整合&#xff0c;以提高开发效率、代码质量和可维护性的一种技术和实践方法。其核心目的是使得前端开发变得更高效、可扩展和可维护。 文章目录 一、Vue 项…

Spingboot 定时任务与拦截器(详细解释)

在 boot 环境中&#xff0c;一般来说&#xff0c;要实现定时任务&#xff0c;我们有两中方案&#xff0c;一种是使用 Spring 自带的定时 任务处理器 Scheduled 注解&#xff0c;另一种就是使用第三方框架 Quartz &#xff0c; Spring Boot 源自 SpringSpringMVC &#…

无人机+无人车+无人狗+无人船:互通互联技术探索详解

关于“无人机无人车机器狗&#xff08;注&#xff1a;原文中的“无人狗”可能是一个笔误&#xff0c;因为在实际技术领域中&#xff0c;常用的是“机器狗”这一术语&#xff09;无人船”的互通互联技术&#xff0c;以下是对其的详细探索与解析&#xff1a; 一、系统架构与关键…

ima.copilot-腾讯智能工作台

一、产品描述 ima.copilot是腾讯推出的基于腾讯混元大模型技术的智能工作台&#xff0c;通过先进的人工智能技术&#xff0c;为用户提供了一个全新的搜读写体验&#xff0c;让知识管理变得更加智能和高效。它不仅是一个工具&#xff0c;更是一个智能的伙伴&#xff0c;能够帮助…

集合卡尔曼滤波(EnsembleKalmanFilter)的MATLAB例程(三维、二维)

本 M A T L A B MATLAB MATLAB代码实现了一个三维动态系统的集合卡尔曼滤波&#xff08;Ensemble Kalman Filter, EnKF&#xff09;示例。代码的主要目的是通过模拟真实状态和测量值&#xff0c;使用 EnKF 方法对动态系统状态进行估计。 文章目录 参数设置初始化真实状态定义状…

【动手学电机驱动】STM32-FOC(5)基于 IHM03 的无感 FOC 控制

STM32-FOC&#xff08;1&#xff09;STM32 电机控制的软件开发环境 STM32-FOC&#xff08;2&#xff09;STM32 导入和创建项目 STM32-FOC&#xff08;3&#xff09;STM32 三路互补 PWM 输出 STM32-FOC&#xff08;4&#xff09;IHM03 电机控制套件介绍 STM32-FOC&#xff08;5&…

光老化测试的三种试验:紫外老化、氙灯老化、碳弧灯老化

光老化是指材料在阳光照射下&#xff0c;由于紫外线、热和氧气的共同作用而发生的物理和化学变化。这种现象对纺织材料、塑料材料、涂料材料和橡胶材料的应用有显著影响。这些材料户外家具、汽车内饰和户外供水排水管道、建筑外墙涂料、汽车漆面、船舶涂料、汽车轮胎、密封件、…

VMWare安装包及安装过程

虚拟机基本使用 检查自己是否开启虚拟化 如果虚拟化没有开启&#xff0c;需要自行开启&#xff1a;百度加上自己电脑的品牌型号&#xff0c;进入BIOS界面开启 什么是虚拟机 所谓的虚拟机&#xff0c;就是在当前计算机系统中&#xff0c;又开启了一个虚拟系统 这个虚拟系统&…

消费的外部性

大学宿舍&#xff0c;遇到在你睡觉的时候开外放不戴耳机的室友&#xff0c;但中午12点&#xff0c;室友却在那拉上窗帘睡觉。能带饭吗&#xff1f;能代签到吗&#xff1f;能倒个垃圾吗&#xff1f;能带个外卖吗&#xff1f;自己永远麻烦别人&#xff0c;你要让他帮个忙又这推那…

易趋亮相2024 PMI项目管理大会

11月9日-10日&#xff0c;2024 PMI项目管理大会在广州圆满举办&#xff0c;项目管理行业优秀代表企业——易趋&#xff08;隶属深圳市蓝云软件有限公司&#xff09;&#xff0c;携最新产品和解决方案亮相本次展会。 (主论坛现场&#xff09; 本届大会以“‘项’有所成 行以致远…

边缘计算与推理算力:智能时代的加速引擎

在数据量爆炸性增长的今天&#xff0c;边缘计算与推理算力正成为推动智能应用的关键力量。智能家居、自动驾驶、工业4.0等领域正在逐步从传统的云端计算转向边缘计算&#xff0c;而推理算力的加入&#xff0c;为边缘计算提供了更强的数据处理能力和实时决策能力。本文将探讨边缘…

基于matlab的CNN食物识别分类系统,matlab深度学习分类,训练+数据集+界面

文章目录 前言&#x1f393;一、数据集准备&#x1f393;二、模型训练&#x1f340;&#x1f340;1.初始化&#x1f340;&#x1f340;2.加载数据集&#x1f340;&#x1f340;3.划分数据集&#xff0c;并保存到新的文件夹&#x1f340;&#x1f340;4.可视化数据集&#x1f34…

马斯克万卡集群AI数据中心引发的科技涟漪:智算数据中心挑战与机遇的全景洞察

一、AI 爆发重塑数据中心格局 随着AI 技术的迅猛发展&#xff0c;尤其是大模型的崛起&#xff0c;其对数据中心产生了极为深远的影响。大模型以其数以亿计甚至更多的参数和对海量数据的处理需求&#xff0c;成为了 AI 发展的核心驱动力之一&#xff0c;同时也为数据中心带来了…

移远通信亮相骁龙AI PC生态科技日,以领先的5G及Wi-Fi产品革新PC用户体验

PC作为人们学习、办公、娱乐的重要工具&#xff0c;已经深度融入我们的工作和生活。随着物联网技术的快速发展&#xff0c;以及人们对PC性能要求的逐步提高&#xff0c;AI PC成为了行业发展的重要趋势。 11月7-8日&#xff0c;骁龙AI PC生态科技日在深圳举办。作为高通骁龙的重…

Unity资源打包Addressable资源保存在项目中

怎么打包先看“Unity资源打包Addressable AA包” 其中遗留一个问题&#xff0c;下载下来的资源被保存在C盘中了&#xff0c;可不可以保存在项目中呢&#xff1f;可以。 新建了一个项目&#xff0c;路径与“Unity资源打包Addressable AA包”都不相同了 1.创建资源缓存路径 在…

postman变量和脚本功能介绍

1、基本概念——global、collection、environment 在postman中&#xff0c;为了更好的管理各类变量、测试环境以及脚本等&#xff0c;创建了一些概念&#xff0c;包括&#xff1a;globals、collection、environment。其实在postman中&#xff0c;最上层还有一个Workspaces的概…

为什么汽车电源正在用 48V 取代 12V

欧姆定律也有利于 48 伏电源 假设您需要为汽车的起动电机供电。可能存在以下静态和动态特征&#xff1a; 电源电压&#xff1a;12V 额定电流&#xff1a;40A 额定功率&#xff1a;480W 标称平均阻抗&#xff1a;0.3Ω 浪涌电流&#xff1a;150A 浪涌功率&#xff1a;1,8…

【webrtc】 RTP 中的 MID(Media Stream Identifier)

RTP 中的 MID(Media Stream Identifier) RID及其与MID的区别 cname与mid的对比【webrtc】CNAME 是rtprtcp中的Canonical Name(规范化名称) 同样都是RTP头部扩展: 基于mediasoup的最新的代码,学习,发现mid在创建RtpSendStream时是必须传递的参数: 例如 D:\XTRANS\soup\…

酷炫的鼠标移入效果(附源码!!)

预览效果 源码(htmljs部分) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>…