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