網(wǎng)站首頁 編程語言 正文
最近要用到滑動(dòng)條,Qt自帶的QSlider雖然能滿足需求,但是操作起來有很多不舒服的地方,于是在它的基礎(chǔ)上改了改,分享給大家使用。
先放效果圖
在QSlider的基礎(chǔ)上,改變了樣式,繪制了刻度,增加了取整功能,只需要微調(diào)就能適應(yīng)各種需求。
1、頭文件
需要包含下面的東西
#include <QSlider>
#include <QtCore>
#include <QStylePainter>
#include <QStyleOptionSlider>
#include <QMouseEvent>
2、聲明
需要繼承QSlider,并重寫兩個(gè)鼠標(biāo)事件mousePressEvent和mouseReleaseEvent,使用paintEvent用來繪制刻度線,使用信號(hào)發(fā)送選中的數(shù)值。
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);
};
3、構(gòu)造函數(shù)
首先在構(gòu)造函數(shù)中配置控件的相關(guān)屬性,在此宏定義的幾個(gè)數(shù)值:nMin和nMax代表取值范圍,nSingleStep代表步長,nTick代表刻度間隔,nWidth和nHeight控制控件的大小。
通過設(shè)置Orientation為Horizontal,使控件為橫向。
#include "myslider.h"
int nMin = 0;
int nMax = 100;
int nSingleStep = 10;
int nTick = 10; //修改刻度個(gè)數(shù)改此數(shù)值
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);
4、設(shè)置樣式表
QSlider::groove控制背景樣式,QSlider::handle控制滑塊樣式,QSlider::sub-page控制劃過區(qū)域的樣式。
需要注意的是,qss和QSlider自帶的刻度線并不兼容,使用qss就不能顯示自帶的刻度線了,但是后文我提供了解決方法。
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;}");
}
5、重寫鼠標(biāo)點(diǎn)擊事件
之所以要這么做,是因?yàn)镼Slider的點(diǎn)擊效果是一格一格地移動(dòng),我希望滑塊能直接跳到指定位置,所以需要用到setValue。
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);
}
}
6、重寫鼠標(biāo)釋放事件
因?yàn)橄M≈悼梢匀讉€(gè)固定的值,此處限定只能取0, 0.1, 0.2… 1這些值,所以在釋放時(shí)對(duì)當(dāng)前值四舍五入,然后讓滑塊移動(dòng)到相應(yīng)的位置。最后發(fā)出信號(hào)傳遞數(shù)值。
void MySlider::mouseReleaseEvent(QMouseEvent *event)
{
//獲取當(dāng)前點(diǎn)擊位置
int currentX = event->pos().x();
//獲取當(dāng)前點(diǎn)擊的位置占整個(gè)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;
//利用算得的百分比得到具體數(shù)字
int value = per*(this->maximum() - this->minimum()) + this->minimum();
//設(shè)定滑動(dòng)條位置
this->setValue(value);
//滑動(dòng)條移動(dòng)事件等事件也用到了mousePressEvent,加這句話是為了不對(duì)其產(chǎn)生影響,是的Slider能正常相應(yīng)其他鼠標(biāo)事件
QSlider::mousePressEvent(event);
emit sliderValue(per);
}
7、繪制刻度
前文提到了qss和QSlider刻度的沖突,所以這里我們直接使用paintEvent畫線。
修改宏定義的參數(shù)值,刻度的數(shù)量也會(huì)隨之變動(dòng)。
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);
}
8、實(shí)際使用
拖動(dòng)或點(diǎn)擊滑動(dòng)條都會(huì)發(fā)出信號(hào),傳遞滑塊對(duì)應(yīng)的值。
所以在要使用的地方建立信號(hào)槽,就可以接收對(duì)應(yīng)滑動(dòng)條傳來的值并加以處理。
FaceThreshSlider = new MySlider(this);
connect(FaceThreshSlider, SIGNAL(sliderValue(float)), this, SLOT(setSlideThresh(float)));
原文鏈接:https://blog.csdn.net/nchu_zhangyiqing/article/details/122490710
相關(guān)推薦
- 2023-04-24 python中argparse模塊及action='store_true'詳解_python
- 2022-06-06 webpack4.0-解決webpack 報(bào)The 'mode' option has not be
- 2022-01-31 jq監(jiān)聽input type="file"發(fā)生改變,即選擇文件,并獲取文件名稱
- 2022-03-14 Token跨域問題Response to preflight request doesn‘t pas
- 2022-05-28 pycharm安裝深度學(xué)習(xí)pytorch的d2l包失敗問題解決_python
- 2024-02-28 UNI-APP中,swiper和tabbar結(jié)合實(shí)現(xiàn)滑動(dòng)翻頁效果
- 2022-11-06 React?Hooks--useEffect代替常用生命周期函數(shù)方式_React
- 2022-05-20 python使用數(shù)字與字符串方法技巧_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支