Qt自定义QSlider(支持水平垂直)

news2024/12/24 8:21:29

实现背景:
Qt本身有自己的QSlider,为什么我们还要自定义实现呢,因为Qt自带的QSlider存在一个问题,当首尾为圆角时,滑动滚动条到首尾时会出现圆角变成矩形的问题。当然如果QSS之间的margin和滑动条的圆角控制的好的话是不会出现这个问题的,但是我们一般都是按照美工设计来完成工作的,如果她的设计是必须一摸一样的话,这个margin和圆角配合不了出现以上问题的话,那我们就需要实现一个自定义的QSlider了。

实现思路:
1、继承QWidget或者QSlider都可以,当然如果我们继承QSlider的话,那还不如使用重写QStyle的方式来重绘。
2、使用paintevent绘制事件来进行重绘。
3、配合mouse鼠标事件实现拖动功能。
4、配合resizeEvent事件来实现自适应大小。

实现效果:
请添加图片描述

实现代码:
头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPainter>
#include <QMouseEvent>

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void reset();   //复位
    void setDirection(int dire){m_direction = dire;}
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void resizeEvent(QResizeEvent *event);
    void paintEvent(QPaintEvent *event);
signals:
    void sig_Run();
private:
    QRect m_handleRect;
    bool m_pressFlag = false;
    bool m_autoFg = false;
    int m_lastX = 0;
    int m_lastY = 0;
    int m_direction = 0; //0:水平,1:垂直
    QPixmap m_handlepix;
};


#endif // WIDGET_H


cpp文件:

#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent)
{

}

Widget::~Widget()
{
}

void Widget::resizeEvent(QResizeEvent *event)
{
    if (m_direction == 0)
        m_handleRect = QRect(1,1,height(),height() - 2);
    else
        m_handleRect = QRect(1,height() - width(),width(),width() - 2);
}
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter p(this);


    p.setRenderHint(QPainter::Antialiasing);
    p.setPen(QColor("#ffffff"));
    p.setBrush(QColor("#ffffff"));
    if (m_direction == 0)
        p.drawRoundedRect(this->rect(),height()/2,height()/2);
    else
        p.drawRoundedRect(this->rect(),width()/2,width()/2);

    //滑轨前半部分
    QLinearGradient linearGradient(QPoint(0,0),QPoint(0,height()));
    linearGradient.setColorAt(0,QColor("#56B478"));
    linearGradient.setColorAt(0.7,QColor("#006009"));
    linearGradient.setColorAt(1,QColor("#56B478"));
    QBrush brush(linearGradient);
    p.setBrush(brush);
    if (m_direction == 0)
        p.drawRoundedRect(QRect(1,1,m_handleRect.right(),height()-2),height()/2,height()/2);
    else
        p.drawRoundedRect(QRect(1,1,width(),m_handleRect.bottom()-2),width()/2,width()/2);

    //滑轨后半部分
    QBrush brush1(QColor("#606060"));
    p.setBrush(brush1);
    if (m_direction == 0)
        p.drawRoundedRect(QRect(m_handleRect.left(),1,width() - m_handleRect.left() - 2,height()-2),height()/2,height()/2);
    else
        p.drawRoundedRect(QRect(1,m_handleRect.top(),width()-2,height() - m_handleRect.top()),width()/2,width()/2);

    //文本
    p.setPen(QColor("#ffffff"));
    p.setBrush(QColor("#ffffff"));
    p.setFont(QFont("Microsoft YaHei",8));
    p.drawText(2*width()/3,0,width()/3,height(),Qt::AlignCenter,"进度条");

    //滑动块
    //    p.drawPixmap(m_handleRect,m_handlepix);
    p.setPen(QColor("#ffffff"));
    p.setBrush(QColor("#842245"));
    p.drawEllipse(m_handleRect);
}


void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug()<<m_handleRect<<event->pos();
    if (m_handleRect.contains(event->pos()))
    {
        m_pressFlag = true;
    }

}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    if (m_pressFlag)
    {
        if (m_direction == 0)
        {
            int x = event->x();
            if (event->x() >= this->rect().right())
                x = this->rect().right() - 1;
            qDebug()<<x<<m_lastX<<width();
            if (x > this->rect().right() - m_handleRect.width())
                x = this->rect().right() - m_handleRect.width();
            if (x < 0)
                x = 0;
            m_handleRect = QRect(x,m_handleRect.y(),m_handleRect.width(),m_handleRect.height());
            if (m_autoFg)
            {
                if (x > m_lastX && m_handleRect.right() >= this->rect().right() - width()/3)
                {
                    m_handleRect = QRect(this->rect().width() - m_handleRect.width() - 1,m_handleRect.y(),m_handleRect.width(),m_handleRect.height());
                }
                else if (m_handleRect.left() <= 0)
                    m_handleRect = QRect(1,m_handleRect.y(),m_handleRect.width(),m_handleRect.height());
                m_lastX = x;
            }
        }
        else
        {
            int  y = event->y();
            if (event->y() >= this->rect().bottom())
                y = this->rect().bottom() - 1;
            if (y > this->rect().bottom() - m_handleRect.height())
                y = this->rect().bottom() - m_handleRect.height();
            if (y < 0)
                y = 0;
            m_handleRect = QRect(m_handleRect.x(),y,m_handleRect.width(),m_handleRect.height());
            if (m_autoFg)
            {
                if (y < m_lastY && m_handleRect.top() <= height()/3)
                {
                    m_handleRect = QRect(m_handleRect.x(),1,m_handleRect.width(),m_handleRect.height());
                }
                m_lastY = y;
            }
        }

        update();
    }
}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    //auto
    if (m_autoFg)
    {
        if (m_handleRect.right() != this->rect().right() - 1)
        {
            m_handleRect = QRect(1,m_handleRect.y(),m_handleRect.width(),m_handleRect.height());
            update();
        }
        else {
            emit sig_Run();
        }
    }
    else
        emit sig_Run();
    m_pressFlag = false;

}

void Widget::reset()
{
    m_handleRect = QRect(1,m_handleRect.y(),m_handleRect.width(),m_handleRect.height());
    update();
}


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

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

相关文章

ModStartBlog v8.2.0 独立友情链接页面,博客列表样式优化

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装 …

【系统设计系列】异步和网络通信

系统设计系列初衷 System Design Primer&#xff1a; 英文文档 GitHub - donnemartin/system-design-primer: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards. 中文版&#xff1a; https://github.com/donnemarti…

【DevOps核心理念基础】2. 敏捷开发与DevOps关系

一、什么是敏捷开发 ? 1.1 敏捷开发的核心模型 二、敏捷开发的要点 2.1 敏捷开发 > 执行细节 2.2 敏捷开发 > 思路的转变 客户需求&#xff1a;提升出行速度 三、敏捷开发 与 DevOps 四、DevOps 实践的度量标准 4.1 怎样判断DevOps实践好与坏? 一、什么是敏捷…

欧科云链研究院:锚定金融市场,香港从STO再出发

作者&#xff5c;Hedy Bi 昨日&#xff0c;据大公报报道&#xff0c;太极资本宣布推出香港首个面向「专业投资者」的房地产基金证券型代币发行&#xff08;STO&#xff09;。集资目标为1亿元。“牌照&#xff0c;醉翁之意不在酒。BTC、ETH等加密资产只是第一步&#xff0c;而背…

Ubuntu搭配POE交换机激活海康威视网络摄像头

前言 一般使用网络摄像头基本有两种方案&#xff1a; 用电源线和网线连接路由器&#xff08;交换机&#xff09;与网络摄像头用两根网线连接路由器交换机网络摄像头&#xff08;前提&#xff1a;交换机和网络摄像头都支持POE协议通电&#xff09; 踩坑日志 由于第一次使用网…

MySQL与ES数据同步之同步调用

这是第一种方法&#xff0c;也是最简单的方法&#xff0c;在对mysql进行增删改查时&#xff0c;操作后直接调用ES方法实现增删改查。 可以看出这种方式业务逻辑简单&#xff0c;实时性高&#xff0c;但是会有业务强耦合&#xff0c;存在双写失败丢数据风险&#xff0c;性能也比…

趣解设计模式之《为什么租房子要找中介?》

〇、小故事 小王大学毕业了&#xff0c;打算来北京闯荡一下&#xff0c;于是就先寄宿到了他的表姐家&#xff0c;白天的时候&#xff0c;自己在外面小区转一转&#xff0c;看看能不能找到可以租到的房子&#xff0c;他找了好几天都没有找到合适的&#xff0c;要么就是小区里一…

每天40min,我们一起用70天稳扎稳打学完《JavaEE初阶》——33/70 第三十三天【JavaScript(webapi)】

JavaScript WebAPI WebAPI 背景知识DOM 基本概念获取元素事件初识操作元素输入密码的 显示 和隐藏点击计数器勾选复选框获取/修改 样式 属性开关灯WebAPI 背景知识 DOM 基本概念 获取元素 事件初识

JUC简介与环境搭建

1.新建一个Maven项目 2.导入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency> 3.检查Java版本 4.什么是JUC JUC&#xff08;java.util.co…

vue-tabel 中使用 el-autocomplete 出现的问题

必须加 :popper-append-to-body"false" :popper-class"vxetableignoreclear" 我自己用的话缺一不可 说一下我自己项目中遇到的问题吧&#xff0c;我写的是表格中套表格&#xff0c;会出现就是当下拉选的时候用selete是可以用的&#xff0c;但是用blur也…

026-从零搭建微服务-文件服务(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

探索程序员需要掌握的算法?

文章目录 一&#xff1a;引言二&#xff1a;常见算法介绍三&#xff1a;重点算法总结 &#x1f389;欢迎来到数据结构学习专栏~探索程序员需要掌握的算法&#xff1f; ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章…

SoC性能指标ARM内核运算能力

自动驾驶芯片常用的性能评价指标:TOPS,DMIPS,GFLOPS分别说的是啥&#xff1f; TOPS Tera Operation Per Second&#xff0c;表示每秒钟可以进行的操作数量&#xff0c;用于衡量自动驾驶的算力。 众所周知&#xff0c;汽车上最常用的传感器是摄像头&#xff0c;而与之对应的计…

【K8S系列】深入解析k8s网络插件—Canal

序言 做一件事并不难&#xff0c;难的是在于坚持。坚持一下也不难&#xff0c;难的是坚持到底。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记论点蓝色&#xff1a;用来标记论点 在现代容器化应用程序的世界中…

Java密码学之数字签名

密码系统是加密技术及其附带基础工具的实现&#xff0c;以提供信息安全服务。基本密码系统的各种组件是明文&#xff0c;加密算法&#xff0c;密文&#xff0c;解密算法&#xff0c;加密密钥和解密密钥。其中加密密钥和解密密钥是&#xff1a; 加密密钥是发件人已知的值。发送…

Jmeter——结合Allure展示测试报告 _

在平时用jmeter做测试时&#xff0c;生成报告的模板&#xff0c;不是特别好。大家应该也知道allure报告&#xff0c;页面美观。 先来看效果图&#xff0c;报告首页&#xff0c;如下所示&#xff1a; ​编辑 报告详情信息&#xff0c;如下所示&#xff1a; ​编辑 运行run.…

van-list 下拉刷新 触底分页 触底分页事件只加载一次

我是 头部是筛选的条件&#xff0c;&#xff0c;更换不同的状态&#xff0c;显示不同的列表数据&#xff0c;比如 审批中数据是 对的&#xff0c;触底分页也是对的&#xff0c;如果我切换一个状态的话&#xff0c;总共是 15条数据&#xff0c;但是 切换了状态只显示第一页的数据…

Java“牵手”拼多多商品详情数据,拼多多商品详情接口,拼多多API接口申请指南

拼多多商品详情API接口的作用是获取拼多多平台上某个商品的详细信息&#xff0c;包括商品标题、价格、图片、规格、参数、店铺信息等。 开发者可以通过该接口获取到商品的原始数据&#xff0c;方便进行数据分析、价格比较、爬取等操作。通过该接口获取到的商品详情数据可以结合…

(2023|ICLR,)用于一般噪声反演问题的扩散后验采样

Diffusion posterior sampling for general noisy inverse problems 公众号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 进交流群获取资料&#xff09; 目录 0. 摘要 1. 简介 2. 背景 2.1 基于分数的扩散模型 2.2 用扩散模型求解逆问题 3. 扩散后验采样…

接口优化1

接口优化 文章目录 接口优化1. 内容概述2. 集成RabbitMQ2.1 下载2.2 SpringBoot集成RabbitMQ 快速入门1.相关配置2.创建发送者者和接收者 2.3 rabbitmq四种交换模式2.4 秒杀接口优化 1. 内容概述 核心思路:减少对数据库的访问&#xff0c;利用Redis的高并发特性来实现。 系统初…