PySide6从0开始学习的笔记(八) 控件(Widget)之QSlider(滑动条)

QSlider 是 PySide6 中用于实现滑动条交互的控件,支持水平 / 垂直方向,可让用户通过拖动滑块、点击滑动条或使用键盘(上下 / 左右键)调整数值,广泛用于音量调节、亮度控制、参数设置等场景。

一、核心特性

方向支持: 水平(Qt.Horizontal)/ 垂直(Qt.Vertical)
数值范围: 可自定义最小值(minimum)、最大值(maximum)、步长(singleStep/pageStep)
交互方式: 拖动滑块、点击滑动条(按 pageStep 跳转)、键盘操作、setValue 手动设置
信号机制: 数值变化时触发信号,支持实时响应
**样式定制:**可通过 QSS 自定义滑块、轨道样式

二、基本使用步骤

python 复制代码
from PySide6.QtWidgets import QApplication, QWidget, QSlider, QVBoxLayout, QLabel
from PySide6.QtCore import Qt
import sys


class SliderDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QSlider 详解")
        self.resize(400, 200)

        # 1. 创建水平滑动条(默认水平,也可显式指定)
        self.slider = QSlider(Qt.Horizontal, self)

        # 2. 设置数值范围(默认 0-99)
        self.slider.setMinimum(0)  # 最小值
        self.slider.setMaximum(100)  # 最大值

        # 3. 设置步长
        self.slider.setSingleStep(1)  # 键盘上下/左右键步长(默认 1)
        self.slider.setPageStep(10)  # 点击轨道时的步长(默认 10)

        # 4. 设置初始值
        self.slider.setValue(50)

        # 5. 可选:显示刻度
        self.slider.setTickPosition(QSlider.TickPosition.TicksBelow)  # 刻度显示位置(下方)
        self.slider.setTickInterval(10)  # 刻度间隔

        # 6. 绑定信号(数值变化时触发)
        self.slider.valueChanged.connect(self.on_slider_change)

        # 7. 创建标签显示当前值
        self.label = QLabel(f"当前值:{self.slider.value()}", self)

        # 布局
        layout = QVBoxLayout()
        layout.addWidget(self.slider)
        layout.addWidget(self.label)
        self.setLayout(layout)

    def on_slider_change(self, value):
        """滑块值变化的回调函数"""
        self.label.setText(f"当前值:{value}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    demo = SliderDemo()
    demo.show()
    sys.exit(app.exec())
使用默认参数,它的几何尺寸如下:

滑道高2像素,边线1像素,手柄宽高10*21像素。

三、关键属性与方法

1. 核心属性(可通过 set/get 方法访问)
方法 说明
setMinimum(int) / minimum() 设置 / 获取最小值(默认 0)
setMaximum(int) / maximum() 设置 / 获取最大值(默认 99)
setValue(int) / value() 设置 / 获取当前值
setSingleStep(int) / singleStep() 键盘操作步长(默认 1)
setPageStep(int) / pageStep() 点击轨道的步长(默认 10)
setOrientation(Qt.Orientation) 设置方向:Qt.Horizontal / Qt.Vertical
setTickPosition(QSlider.TickPosition) 设置刻度位置(见下表)
setTickInterval(int) / tickInterval() 设置刻度间隔(默认和 singleStep 一致)
2. 刻度位置(QSlider.TickPosition)
常量 说明
TicksAbove 水平滑块:刻度在上方
TicksBelow 水平滑块:刻度在下方
TicksLeft 垂直滑块:刻度在左侧
TicksRight 垂直滑块:刻度在右侧
TicksBothSides 刻度在两侧
NoTicks 不显示刻度(默认)
3. 常用方法
方法 说明
clearMinimum() / clearMaximum() 清除最小 / 最大值限制(恢复默认)
invertAppearance(bool) 反转滑块外观(如:最大值在左 / 上,最小值在右 / 下)
invertControls(bool) 反转键盘 / 鼠标操作方向(如:右键 / 上键减小值)
isSliderDown() 判断滑块是否被鼠标拖动(返回 bool)

四、核心信号

QSlider 继承自 QAbstractSlider,常用信号如下:

信号 触发时机
valueChanged(int value) 数值变化时触发(拖动、点击、键盘、setValue 均会触发)
sliderPressed() 滑块被按下(鼠标点击 / 键盘聚焦并按下方向键)时触发
sliderMoved(int value) 滑块被拖动时实时触发(仅鼠标拖动)
sliderReleased() 滑块释放时触发

信号使用示例(区分拖动和手动设置)

python 复制代码
# 仅监听鼠标拖动的数值变化
self.slider.sliderMoved.connect(lambda val: print(f"拖动到:{val}"))

# 监听滑块按下/释放
self.slider.sliderPressed.connect(lambda: print("滑块被按下"))
self.slider.sliderReleased.connect(lambda: print("滑块被释放"))

五、样式定制(QSS)

通过 QSS 可自定义滑块轨道、滑块手柄、刻度的样式,示例:

python 复制代码
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QSlider
from PySide6.QtCore import Qt
import sys

app = QApplication(sys.argv)

window = QWidget()
window.setWindowTitle("正圆形手柄 QSlider")
layout = QVBoxLayout(window)

slider = QSlider(Qt.Horizontal)
slider.setRange(0, 100)
slider.setValue(30)
slider.setFixedHeight(40)          # 给足高度,防止圆形被裁剪
slider.setStyleSheet("""
    QSlider::groove:horizontal {
        height: 6px;                       /* 滑道厚度 */
        background: #a0a0a0;
        border-radius: 3px;
    }

    QSlider::handle:horizontal {     /*通过定义尺寸,生成一个正圆形的手柄*/
        background: #0078d7;
        border: 0px solid #005a9e;     /*边线宽度 边线颜色*/
        width: 24px;                       /* 宽度=圆直径 */
        height: 0px;                      /* 高度,随便设置 */
        margin: -9px 0;                    /* -(直径-滑道厚度)/2 =-(24-6)/2=-9*/
        border-radius: 12px;                /* 直径/2 = 24/2=12 */
    }

    QSlider::handle:horizontal:hover {
        background: #005a9e;
    }

    QSlider::handle:horizontal:pressed {
        background: #004578;
    }
""")

layout.addWidget(slider)
window.show()
sys.exit(app.exec())
  • 注意,不要在样式表中通过这个调整手柄高度,因为它不起作用:
python 复制代码
 QSlider::handle:horizontal {
        height: xxxpx;                      /* 高度 */
    }

而是使用handle的margin(手柄的边距)与groove的height(滑道的厚度)配合:

手柄高度=(-2*手柄边距)+ 滑道厚度,

比如,手柄边距 = -9,滑道厚度 = 4,那么,手柄高度 = (-2) * (-9) + 4 = 18 + 4 = 22。

验证:

六、常用的QSS设置项:

1、 基础布局与尺寸属性
参数 说明 示例
width 轨道宽度(水平滑块一般不设置,由父控件 / 布局决定) width: 300px;
height 核心参数:轨道的高度(直接影响滑块手柄的显示空间) height: 16px;
min-width 轨道最小宽度 min-width: 200px;
min-height 轨道最小高度 min-height: 10px;
max-width 轨道最大宽度 max-width: 500px;
max-height 轨道最大高度 max-height: 20px;
padding 轨道内边距(上下左右,会压缩轨道的可交互区域) padding: 2px 0;(上下 2px,左右无)
margin 轨道外边距(与父控件的间距) margin: 5px auto;(上下 5px,水平居中)
2、 背景与边框属性
参数 说明 示例
background 轨道背景(支持纯色、渐变、图片) 纯色:background: #f0f0f0;渐变:background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #ddd, stop:1 #bbb);
background-color 单独设置背景色(优先级低于 background background-color: #e5e5e5;
background-image 轨道背景图片 background-image: url(./track.png);
background-repeat 背景图片重复方式 background-repeat: no-repeat;
background-position 背景图片位置 background-position: center;
border 轨道边框(宽度 + 样式 + 颜色) border: 1px solid #cccccc;
border-width 边框宽度(可分方向设置:border-top-width 等) border-width: 1px 0;(仅上下边框)
border-style 边框样式(solid/dashed/dotted 等) border-style: dashed;
border-color 边框颜色 border-color: #999999;
border-radius 常用:轨道圆角半径(实现圆角轨道) border-radius: 8px;(与 height 一半匹配更美观)
border-top-left-radius 单独设置左上角圆角 border-top-left-radius: 4px;
3、 滑块进度段样式(选中部分)

水平滑块可通过 QSlider::groove:horizontal 区分未选中轨道 ,通过 QSlider::sub-page:horizontal 区分滑块左侧已选中的进度段,这两个子选择器可继承上述所有属性,实现双色轨道效果。

示例:

python 复制代码
QSlider::horizontal {
    height: 12px;
    border-radius: 6px;
    background: #f5f5f5; /* 轨道默认背景 */
    }
    /* 滑块左侧的进度段 */
    QSlider::sub-page:horizontal {
        background: #ff0000; /* 红色进度 */
        border-radius: 6px;
    }
    /* 滑块右侧的未选中段(可选) */
    QSlider::add-page:horizontal {
        background: #00ff00; /* 绿色未选中 */
        border-radius: 6px;
    }
4、 状态相关属性

可结合伪状态(如 :hover/:disabled)设置不同状态下的轨道样式:

伪状态 说明
:hover 鼠标悬浮在滑块轨道上时
:disabled 滑块禁用(setDisabled(True))时
:focus 滑块获得焦点时

七、常见应用场景

1. 音量调节(结合 QMediaPlayer)

# 简化示例

python 复制代码
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput

player = QMediaPlayer()
audio_output = QAudioOutput()
player.setAudioOutput(audio_output)

# 滑块控制音量(0-100 转换为 0.0-1.0)
self.slider.valueChanged.connect(lambda val: audio_output.setVolume(val / 100))
  1. 实时调整控件属性(如标签字体大小)
python 复制代码
self.slider.setRange(8, 48)  # 字体大小范围
self.slider.valueChanged.connect(lambda val: self.label.setFont(QtGui.QFont("Arial", val)))
  1. 限制数值为偶数(自定义逻辑)
python 复制代码
def on_value_change(self, value):
    # 强制数值为偶数
    if value % 2 != 0:
        self.slider.setValue(value + 1 if value < self.slider.maximum() else value - 1)
    self.label.setText(f"偶数值:{self.slider.value()}")
  • 一个渐变色滑轨的示例:
python 复制代码
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QSlider
from PySide6.QtCore import Qt
import sys

app = QApplication(sys.argv)

window = QWidget()
window.setWindowTitle("双色滑道 QSlider")
layout = QVBoxLayout(window)

slider = QSlider(Qt.Horizontal)
slider.setRange(0, 100)
slider.setFixedHeight(30)


default_style = """
    QSlider::horizontal {
    height: 8px;
    border-radius: 1px;
    background: #f5f5f5;
    } 

    QSlider::groove:horizontal {
        height: 6px;
        background: #a0a0a0;
        border-radius: 3px;
    }
    
    QSlider::handle:horizontal { 
        background: #0078d7;
        border: 0px solid #005a9e; 
        width: 20px; 
        margin: -9px 0; 
   }
"""
slider.setStyleSheet(default_style)

def set_end_style(value):
    red = str(int(value/100*255))
    end_color = f"rgb({red}, 0, 0)"
    sub_page = f"""QSlider::sub-page:horizontal {{
            background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #00ff00, stop: 1 {end_color});
            border-radius: 6px;
        }}"""
    # print(sub_page)
    set_style = f"{default_style}\n{sub_page}"
    slider.setStyleSheet(set_style)



slider.valueChanged.connect(set_end_style)

layout.addWidget(slider)
window.show()
sys.exit(app.exec())

八、注意事项

**数值范围:**设置 setMinimum/setMaximum 后,setValue 会自动限制在范围内(如设置 105 但最大值 100,实际值为 100)。

**性能优化:**若滑块拖动时需执行耗时操作(如更新图表),建议在 sliderReleased 信号中处理,而非 valueChanged/sliderMoved。

**垂直滑块布局:**垂直滑块需注意布局高度,否则可能显示不全(可设置 minimumHeight)。

**兼容性:**invertAppearance 仅影响外观,不改变数值逻辑;invertControls 会反转所有交互方向。

总结

QSlider 是 PySide6 中灵活的数值调节控件,核心在于掌握数值范围 / 步长设置、信号绑定和样式定制。根据场景选择合适的信号(如实时响应选 sliderMoved,确认值选 sliderReleased),结合 QSS 可实现与界面风格统一的滑动条。

相关推荐
TL滕2 小时前
从0开始学算法——第十九天(并查集练习)
笔记·学习·算法
im_AMBER2 小时前
Leetcode 80 统计一个数组中好对子的数目
数据结构·c++·笔记·学习·算法·leetcode
dazzle2 小时前
《DataFrame可视化与高级方法》
python·pandas
KaDa_Duck2 小时前
DASCTF 2025下半年赛 PWN-CV_Manager复盘笔记
linux·笔记·安全
千殇华来2 小时前
XMOS学习笔记
人工智能·笔记·学习
Blossom.1182 小时前
Transformer时序预测实战:用PyTorch构建股价预测模型
运维·人工智能·pytorch·python·深度学习·自动化·transformer
我命由我123452 小时前
Python Flask 开发问题:ImportError: cannot import name ‘escape‘ from ‘flask‘
服务器·开发语言·后端·python·flask·学习方法·python3.11
baby_hua2 小时前
20251031_三天速通PyTorch
人工智能·pytorch·python
峥嵘life2 小时前
Android16 EDLA 认证BTS测试Failed解决总结
android·java·linux·运维·学习