QT——QSlider实现,QT滑动控件的使用

简介

QT中滑动条的控件叫QSlider,继承自QAbstractSlider类。
主要用途是通过滑块的滑动的方式在一定范围内调节某个值。根据调节的后得到的结果去执行一些处理,比如将值写入或者用这个值进行计算,或者进行值传输等等。
滑块

通常使用这个控件是希望我们调节滑块到指定位置后,发生一个触发事件,在这个触发事件中,我们获取最后的值,然后进行处理操作。
查阅文档发现滑块的一些槽函数触发事件好像都无法直接实现这一目的,滑块的触发事件会多次触发,也就是不是到最后才触发。
UI界面可拖拽使用的Slider如下图,一个是水平的一个是垂直的滑块。

滑动块

滑动块调节两种方法

首先我们简单介绍以下滑动块值变动调节的方法。

在这里插入图片描述

滑动块由滑块和滑动条组成,想要改变滑动块的值有两种方式
1.按下滑动块,进行移动,再松开。
2.点击滑动条,滑动块会朝点击方向进行移动一段距离。这种方法不会按下滑动块(具体多少没有深究,限制值也不知,但是确实不能点到哪,滑动块就直接移动到哪)

注意这两者的区别,前者需要按住,且滑动,后者只需要点击就可以实现。这些操作会影响后面信号量的触发。

滑动条触发信号量

可转换的继承自QAbstractSlider的槽函数有以下6个。
槽函数
其实这6个转换未槽函数的实现就是对应着QAbstractSlider的6个信号量触发函数

//Signals 信号量
 void actionTriggered(int action)
 void rangeChanged(int min, int max)
 void sliderMoved(int value)
 void sliderPressed()
 void sliderReleased()
 void valueChanged(int value)

前面转到槽函数的使用就是依据这6个信号量的触发,执行对应的函数。函数内容自己按需求设计。

 void sliderMoved(int value)

这个信号量触发的条件是按下滑块并滑动,就会发出这个信号量,触发对应的槽函数。需要注意的是只要滑块动就会触发,也就是你从1滑动到10,那么1-10中每有一个值是可取的,它都会触发一次。(我感觉这个信号量废了,除非你真就每次只滑动一格,那你没必要用滑动块了)

 void sliderPressed()

这个信号量是当滑块按下时触发信号量,执行槽函数,一般情况下也不会用吧,因为按下的时候值是没变的,此时触发不需要进行什么操作。

 void sliderReleased()

这个信号量是当滑块释放时,触发信号量可以执行对应的槽函数。这个就比较有用了,可以捕捉到滑动完滑块的那个瞬间,那也是最终的位置,此时的结果正是调节完的结果,执行对应的槽函数去进行值处理。其实这个信号量就可以完成滑块的基本需求了。 但是也还有些局:通过点击滑动块的方式无法触发信号量。

 void valueChanged(int value)

这个信号量是滑块滑动,值发生变化时,就会触发,其实一般使用起来和前面的sliderMoved基本相同,就是少了一个按下滑动块的前提,(不管按不按下滑块)值发生变化时,这个信号量都会触发。同样的从1-10变化,中间每个值都会触发一次。

 void actionTriggered(int action)
 void rangeChanged(int min, int max)

这两个函数的使用不明,也没有深入研究,有知道的大佬可以在评论区留言补充,只知道通过测试,滑动滑块的操作这两个信号量不会触发,猜测是属于如果滑块的属性发生变化了才会触发,比如修改了滑块可滑动值的范围。

理想滑动块运用(参考)

前面提到,我们使用滑块控件是希望进行滑块移动改变值(两种方式),并获取值进行对应的数值操作。

通过sliderReleased()滑动块可以实现基本的拖动滑块来进行值变化并获取最终值触发信号量,在槽函数中进行数值操作。但是提到了有局限:对于点击滑动条进行的值变化无法触发信号量,这样会有一些BUG和不好的体验。

比较理想的使用方式如下:
结合 void sliderReleased(),void valueChanged(int value)一起实现,分别用来判断第一种和第二种改变值的方式。两者结合使用相同的数值处理函数即可实现改功能。
第一种方式直接槽函数实现;
第二种方式需要在槽函数种加一个判断——滑块是否处于按下状态,不处于按下的情况下值发生改变才算是二种方式触发,即点击滑动条实现值变化。
具体实现如下:
1、在UI界面拖动一个滑动块设计界面。

在这里插入图片描述
给控件重命名未“SliderTest”

在这里插入图片描述
选中控件并右键,选中转为槽
在这里插入图片描述

分别实现这两个槽函数。

在这里插入图片描述
之后会在源文件中产生两个槽函数,已经自动绑定好触发事件。无需在手动绑定。

void MainWindow::on_SliderTest_sliderReleased()
{
}

void MainWindow::on_SliderTest_valueChanged(int value)
{
}

同时头文件也会有定义。
最后按前面的逻辑配置槽函数。代码如下:

void MainWindow::on_SliderTest_sliderReleased()
{
    //滑动块释放触发,第一种变值方式
    valueChange(ui->SliderTest->value());//获取当前滑动控件值并传入
}

void MainWindow::on_SliderTest_valueChanged(int value)
{
    if(!(ui->SliderTest->isSliderDown())){//判断滑块是否未按下
        //实现点击滑动条切值,第二种变值方式
        valueChange(value);
    }else{
        //滑动触发,会多次触发,不建议进行操作处理,特殊情况除外
    }
}
void MainWindow::valueChange(int value){
    //值变化的数值处理。
}

isSliderDown()判断滑块是否按下
只需要在valueChange()函数中,编写自己需要的数值处理逻辑即可。
注意:“ MainWindow::”这个类名要改为和自己一样的,另外函数valueChange()需要自己添加定义到头文件。

void valueChange(int value);

以上就是全部内容了,有点啰嗦,欢迎批评指正,有更好的方法欢迎评论区留言。

### 回答1: 可以通过继承QSlider类并重写paintEvent()函数来自定义QSlider滑动条,同时可以通过设置QStyleOptionSlider中的subControls属性来设置滑块的形状为圆形。具体实现可以参考以下代码: ``` class CustomSlider : public QSlider { public: CustomSlider(QWidget *parent = nullptr) : QSlider(parent) { setStyleSheet("QSlider::groove:horizontal { height: 10px; background: #ddd; }" "QSlider::handle:horizontal { width: 20px; border-radius: 10px; background: #333; }"); } protected: void paintEvent(QPaintEvent *event) override { QSlider::paintEvent(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QStyleOptionSlider opt; initStyleOption(&opt); QRect grooveRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); QRect handleRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); QPoint center = handleRect.center(); painter.setPen(Qt::NoPen); painter.setBrush(QColor("#333")); painter.drawEllipse(center, handleRect.width() / 2, handleRect.height() / 2); } }; ``` 在上述代码中,我们通过设置QSlider的样式表来设置滑动条的样式,其中groove表示滑动条的轨道,handle表示滑块。在paintEvent()函数中,我们首先调用QSlider的paintEvent()函数来绘制默认的滑动条,然后获取滑动条的轨道和滑块的矩形区域,并计算出滑块的中心点。最后,我们使用QPainter绘制一个圆形,将其填充为黑色,并以滑块的中心点为圆心,滑块宽度的一半为半径进行绘制,从而实现了圆形滑块的效果。 ### 回答2: QT是一款跨平台的C++图形用户界面应用程序开发框架。在QT中,我们可以自定义QSlider滑动条以及滑块的形状。 要自定义QSlider滑动条,首先我们需要创建一个自定义的滑动条类,继承QSlider。在该类中,我们可以重写一些QSlider的虚函数,如paintEvent()、sliderChange()等,以实现自定义的滑动条样式和功能。 要实现圆形的滑块,我们可以通过设置滑块样式表来实现。在QSlider的子类中,通过重写paintEvent()函数,我们可以在滑动条上绘制自定义的滑块。 以下是一个自定义的QSlider滑动条,滑块为圆形的示例代码: ```cpp class CustomSlider : public QSlider { Q_OBJECT public: CustomSlider(QWidget *parent = nullptr) : QSlider(parent) { setStyleSheet("QSlider::handle {" " background: green;" " border-radius: 8px;" " width: 16px;" " height: 16px;" "}"); } protected: void paintEvent(QPaintEvent *event) override { QSlider::paintEvent(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); QRect grooveRect = style()->subControlRect(QStyle::CC_Slider, this, QStyle::SC_SliderGroove, this); int x = grooveRect.x() + grooveRect.height() / 2 - 8; int y = grooveRect.y() + grooveRect.height() / 2 - 8; painter.setBrush(QColor(51, 153, 255)); painter.setPen(Qt::NoPen); painter.drawEllipse(QRect(x, y, 16, 16)); } }; ``` 在上述代码中,我们重写了CustomSlider的构造函数和paintEvent()函数。构造函数中通过设置样式表,将滑块的背景设为绿色,圆角半径设为8px,并设置滑块的大小为16x16px。paintEvent()函数中,我们通过获取滑动条的轨道区域,计算滑块的位置,然后绘制一个蓝色圆形作为滑块。 我们可以在应用程序中使用CustomSlider类来替代QSlider类,从而实现自定义的滑动条和圆形滑块。 ### 回答3: 要自定义QSlider滑动条,使滑块圆形,可以通过重写QStyle类的drawComplexControl方法来实现。具体步骤如下: 1. 创建一个继承自QStyle的自定义样式类,并重写drawComplexControl方法。 2. 在drawComplexControl方法中,首先调用父类的drawComplexControl方法,这样可以绘制默认样式的滑块。 3. 获取滑块的矩形区域,并将其设置为圆形。 4. 根据滑块的圆形矩形区域,绘制一个圆形。 5. 最后,将自定义样式类应用到QSlider控件上。 下面是实现上述步骤的示例代码: ```C++ #include <QtWidgets> class CustomSliderStyle : public QStyle { public: using QStyle::QStyle; void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget = nullptr) const override { if (control == CC_Slider && option->subControls == SC_SliderHandle) { QStyleOptionSlider opt = *qstyleoption_cast<const QStyleOptionSlider*>(option); // 绘制默认样式的滑块 QStyle::drawComplexControl(control, option, painter, widget); // 获取滑块的矩形区域 QRect grooveRect = subControlRect(CC_Slider, option, SC_SliderHandle, widget); QRect handleRect = opt.rect; // 将滑块的矩形区域设置为圆形 handleRect.setSize(QSize(handleRect.width(), handleRect.width())); handleRect.moveCenter(grooveRect.center()); // 绘制圆形滑块 painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); painter->setBrush(opt.palette.buttonText()); painter->drawEllipse(handleRect); painter->restore(); } else { QStyle::drawComplexControl(control, option, painter, widget); } } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QSlider slider; CustomSliderStyle customStyle; slider.setStyle(&customStyle); slider.show(); return app.exec(); } ``` 通过以上代码,可以自定义QSlider滑动条,使滑块变为圆形。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值