最近要用到滑动条,Qt自带的QSlider虽然能满足需求,但是操作起来有很多不舒服的地方,于是在它的基础上改了改,分享给大家使用。
在QSlider的基础上,改变了样式,绘制了刻度,增加了取整功能,只需要微调就能适应各种需求。
#include
#include
#include
#include
#include
class MySlider : public QSlider
{
Q_OBJECT
public:
MySlider(QWidget *parent = nullptr);
~MySlider();
signals:
void sliderValue(float);
private:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *ev);
};
#include "myslider.h"
int nMin = 0;
int nMax = 100;
int nSingleStep = 10;
int nTick = 10; //修改刻度个数改此数值
int nWidth = 200;
int nHeight = 50;
MySlider::MySlider(QWidget *parent):
QSlider (parent)
{
setOrientation(Qt::Horizontal);
setFixedSize(nWidth,nHeight);
setMinimum(nMin);
setMaximum(nMax);
setSingleStep(nSingleStep);
setTickInterval(nTick);
setTickPosition(QSlider::TicksAbove);
setStyleSheet("QSlider::groove:horizontal{height:12px; left:0px; right:0px; border:0px; border-radius:6px; background:rgb(242,242,242);} \
QSlider::handle:horizontal{width:24px; background:#1644B0; border-radius:12px; margin:-6px 0px;} \
QSlider::sub-page:horizontal{background:#4C85FB; border:0px; border-radius:6px;}");
}
void MySlider::mousePressEvent(QMouseEvent * event)
{
int pointPos = ((double)event->pos().x()) / (this->width() * (nMax - nMin) + nMin);
if(pointPos != 0){
if(abs(pointPos - this->value()) > nTick){
this->setValue(pointPos);
}
}
else{
QSlider::mousePressEvent(event);
}
}
void MySlider::mouseReleaseEvent(QMouseEvent *event)
{
//获取当前点击位置
int currentX = event->pos().x();
//获取当前点击的位置占整个Slider的百分比
float per = currentX *1.0 /this->width();
//限制边界
if(per > 1) per = 1;
else if(per < 0) per = 0;
//按步长取整
per = (float)(qRound(per * 100 / nTick) * nTick) / 100;
//利用算得的百分比得到具体数字
int value = per*(this->maximum() - this->minimum()) + this->minimum();
//设定滑动条位置
this->setValue(value);
//滑动条移动事件等事件也用到了mousePressEvent,加这句话是为了不对其产生影响,是的Slider能正常相应其他鼠标事件
QSlider::mousePressEvent(event);
emit sliderValue(per);
}
void MySlider::paintEvent(QPaintEvent *)
{
QStylePainter p(this);
QStyleOptionSlider opt;
initStyleOption(&opt);
// 获取滑块的大小
QRect handle = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
// draw tick marks
// do this manually because they are very badly behaved with style sheets
int interval = tickInterval();
if (interval == 0)
{
interval = pageStep();
}
if (tickPosition() != NoTicks)
{
for (int i = minimum(); i <= maximum(); i += interval)
{
int x = round((double)((double)((double)(i - this->minimum()) / (double)(this->maximum() - this->minimum())) * (double)(this->width() - handle.width()) + (double)(handle.width() / 2.0))) - 1;
int h = 4;
p.setPen(QColor("#a5a294"));
if (tickPosition() == TicksBothSides || tickPosition() == TicksAbove)
{
int y = this->rect().top();
p.drawLine(x, y, x, y + h);
}
if (tickPosition() == TicksBothSides || tickPosition() == TicksBelow)
{
int y = this->rect().bottom();
p.drawLine(x, y, x, y - h);
}
}
}
// draw the slider (this is basically copy/pasted from QSlider::paintEvent)
opt.subControls = QStyle::SC_SliderGroove;
p.drawComplexControl(QStyle::CC_Slider, opt);
// draw the slider handle
opt.subControls = QStyle::SC_SliderHandle;
p.drawComplexControl(QStyle::CC_Slider, opt);
}
FaceThreshSlider = new MySlider(this);
connect(FaceThreshSlider, SIGNAL(sliderValue(float)), this, SLOT(setSlideThresh(float)));