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

实现背景:
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();
}


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您好!感谢您的提问! 要自定义QSlider的滑动条,可以使用Qt样式表(QSS)。以下是一个示例代码,演示如何将QSlider的滑动条和边框样式定制为圆形和阴影效果: ```python # -*- coding: utf-8 -*- from PyQt5.QtWidgets import QApplication, QWidget, QSlider from PyQt5.QtGui import QPainter from PyQt5.QtCore import Qt class MySlider(QSlider): def __init__(self, parent=None): super().__init__(parent) self.setStyleSheet(''' QSlider::groove:horizontal { border: none; height: 4px; background-color: rgba(255, 255, 255, 150); border-radius: 2px; } QSlider::sub-page:horizontal { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 rgba(255, 255, 255, 200), stop: 1 rgba(255, 255, 255, 0)); border-radius: 2px; } QSlider::handle:horizontal { width: 10px; margin-top: -3px; margin-bottom: -3px; border-radius: 5px; background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #f6f7fa, stop:1 #dadbde); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); } QSlider::handle:horizontal:hover { background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #dadbde, stop:1 #f6f7fa); } QSlider::handle:horizontal:pressed { background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #dadbde, stop:1 #f6f7fa); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.35); } ''') def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.translate(0, self.height() / 2) painter.setPen(Qt.NoPen) # Draw border shadow = QtGui.QRadialGradient(0, 0, 60, 0, 0) shadow.setColorAt(0, QtGui.QColor(0, 0, 0, 50)) shadow.setColorAt(1, QtGui.QColor(0, 0, 0, 0)) painter.setBrush(QtGui.QBrush(shadow)) painter.drawEllipse(-32, -32, self.width() + 64, self.width() + 64) # Draw circle painter.setBrush(QtGui.QColor(255, 255, 255)) painter.drawEllipse(self.rect().adjusted(20, 20, -20, -20)) # Draw slider handle self.drawSliderHandle

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值