使用pygame库实现滑动条(slider)

一、为何而写

pygame中并没有滑动条,但滑动条的应用确实很广泛,为此我仿照tkinter中的slider写了一个在pygame中实现的滑动条,与大家共同交流。

二、程序运行结果

程序运行后结果如图:

可以用鼠标拖动滑动改变其值,当前值会根据滑块位置在左侧或右侧显示,并返回到对应变量中,方便程序中引用。

三、参数说明

滑动条以class的方式定义,设定了一些参数,在使用时直接定义就行,有些有默认值。

下面代码为初始化及关参数:

class 滑动条():

    def __init__(self,scr,坐标x,坐标y,宽度,高度,初始值=0,最小值=0,最大值=100,步长=1,bg=(28,28,255),滑块颜色=(128,128,128),fg=(255,255,0),active_bg=(76,155,226),active_滑块颜色=(255,128,255),fontsize=16,取整=True,显示数据=True,小数位数=2,无限大=False,无限大值=sys.maxsize,无限大提示='无限大') -> None:

程序定义了一个横向的条形滑动条,参数如下:(有些参数用了中文哦,不习惯的可以自己改)

        scr:输出到的surface

        坐标x,坐标y:在scr中的左上角坐标

        宽度,高度:滑动条的宽度和高度,宽度不能小于30,高度要大于字体大小!!!

        初始值:初始值 初始值一定要在最大值和最小值之间!!!

        最小值,最大值:定义按钮取值区间,默认值是0 和 100 ,值太小时请把 取整 = False

        步长:每次调整量,必须 > 0

        bg:主颜色,即滑动条的颜色

        滑块颜色:按滑块可以滑动的滑块颜色

        fg:显示实际值的字体颜色

        active_bg:光标移动到其上面时的背景颜色

        active_滑块颜色:光标移动到滑块上面时的滑块颜色

        fontsize:字大小

        取整:显示的数值是否取整

        显示数据:是否显示数据

        小数位数: 在非取整条件时,保留小数点后几位。在取整状态下无效

        无限大:为False时,没无限大;为True时,当数值>=最大值 时,则无限大,并提示 无限大提示

        无限大值:当处于无限大时,无限大的值,如果没有指定,默认为系统最大值sys.maxsize,即系统支持的最大值

        无限大提示:当处于无限大时,显示的内容,如果没有指定,默认为 “无限大”

        返回值:滑块对应的实际值;当 无限大 为True时,返回 无限大值 指定的值

        以上值均在初始化时定义。

四、完整代码

复制代码就可以运行,每个滑动条应带一个说明,这个版本没有写,以后有时间我会改写一下,说明就需要你自己先写了哦。

# encoding:utf-8
# Copyright (C) 2021-2024  Liu Qinghao
#下面是一个使用pygame库实现的简单滑动条(slider)程序的例子。这个程序创建了一个窗口,并在其中放置了几个滑动条。滑动条的位置和值可以通过鼠标拖动来改变。
__author__ = 'Liu Qinghao' # youkuaiyun.com 学习交流文章

import pygame  
import sys  

class 滑动条():
    def __init__(self,scr,坐标x,坐标y,宽度,高度,初始值=0,最小值=0,最大值=100,步长=1,bg=(28,28,255),滑块颜色=(128,128,128),\
                fg=(255,255,0),active_bg=(76,155,226),active_滑块颜色=(255,128,255),fontsize=16,取整=True,显示数据=True,\
                小数位数=2,无限大=False,无限大值=sys.maxsize,无限大提示='无限大') -> None:
        '''定义长条形 滑动条
        scr:输出到的surface
        坐标x,坐标y:在scr中的左上角坐标
        宽度,高度:滑动条的宽度和高度,宽度不能小于30,高度要大于字体大小!!!
        初始值:初始值 初始值一定要在最大值和最小值之间!!!
        最小值,最大值:定义按钮取值区间,默认值是0 和 100 ,值太小时请把 取整 = False
        步长:每次调整量,必须 > 0
        bg:主颜色,即滑动条的颜色
        滑块颜色:按滑块可以滑动的滑块颜色
        fg:显示实际值的字体颜色
        active_bg:光标移动到其上面时的背景颜色
        active_滑块颜色:光标移动到滑块上面时的滑块颜色
        fontsize:字大小
        取整:显示的数值是否取整
        显示数据:是否显示数据
        小数位数: 在非取整条件时,保留小数点后几位。在取整状态下无效
        无限大:为False时,没无限大;为True时,当数值>=最大值 时,则无限大,并提示 无限大提示
        无限大值:当处于无限大时,无限大的值,如果没有指定,默认为系统最大值sys.maxsize,即系统支持的最大值
        无限大提示:当处于无限大时,显示的内容,如果没有指定,默认为 “无限大”
        返回值:滑块对应的实际值;当 无限大 为True时,返回 无限大值 指定的值
        '''
        self.screen = scr 
        self.display_w = scr.get_rect()[2]
        self.坐标x,self.坐标y = 坐标x,坐标y
        self.宽度,self.高度 = 宽度,高度
        self.刻度外间隔 = 5  # 像素
        self.滑块宽度   = 30 # 像素
        self.滑块有效宽度 = self.宽度 - self.滑块宽度 # 像素
        self.滑块起始x = self.滑块宽度/2 # 像素
        self.滑块终止x = self.宽度-self.滑块宽度/2 # 像素
        self.实际值 = 初始值
        self.最小值 = 最小值
        self.最大值 = 最大值 # 当达到最大值时,显示为最小值,即可以循环
        self.步长 = 步长
        self.每单位值 = (最大值 - 最小值)/self.滑块有效宽度
        self.取整 = 取整
        self.显示数据 = 显示数据
        self.小数位数 = 小数位数
        self.无限大 = 无限大
        self.无限大值 = 无限大值
        self.无限大提示 = 无限大提示
        self.bg = bg               # 滑块槽颜色
        self.active_bg = active_bg # 光标移动到其上面时的背景颜色
        self.滑块颜色 = 滑块颜色
        self.滑块标线颜色 = (200,0,0)
        self.active_滑块颜色 = active_滑块颜色
        self.fg = fg
        self.fontsize = fontsize
        self.控件surface = pygame.Surface((self.宽度,self.高度), pygame.SRCALPHA)
        self.update()
    
    def update(self):
        pos=pygame.mouse.get_pos()
        if self.无限大 and self.实际值 == self.无限大值:
            self.滑块当前x = (self.最大值-self.最小值) / self.每单位值
        else:
            self.滑块当前x = (self.实际值-self.最小值) / self.每单位值   # 像素
        if self.坐标x <= pos[0] <= self.坐标x + self.宽度 and self.坐标y <= pos[1] <= self.坐标y + self.高度 :  # 鼠标在该控件上方
            butt=pygame.mouse.get_pressed()
            if butt[0] :  # 鼠标左键按下
                self.滑块当前x = pos[0] - self.坐标x 
                if self.滑块当前x <= self.滑块起始x :self.滑块当前x = self.滑块起始x
                if self.滑块当前x >= self.滑块终止x :self.滑块当前x = self.滑块终止x+1
                self.实际值 = (self.滑块当前x - self.滑块起始x) * self.每单位值 + self.最小值
                self.滑块当前x -= self.滑块宽度/2
                self.实际值 = self.步长 * ((self.实际值 + self.步长/2) // self.步长)
                if self.取整:
                    self.实际值 = int(round(self.实际值,0)) # 四舍五入取整
                else:
                    self.实际值 = round(self.实际值,self.小数位数) # 四舍五入取整
                    
                if self.实际值 >= self.最大值 : self.实际值 = self.最大值
                if self.实际值 <= self.最小值 : self.实际值 = self.最小值
                if self.无限大 and self.实际值 == self.最大值 :
                    self.实际值 = self.无限大值
                        
            pygame.draw.rect(self.控件surface,self.active_bg, (0,0,self.宽度,self.高度))                      # 滑块槽
            pygame.draw.rect(self.控件surface,(64,64,64), (self.滑块当前x-1,0,self.滑块宽度+2,self.高度),1)    # 滑块阴影,根据值显示到相应位置
            pygame.draw.rect(self.控件surface,self.active_滑块颜色, (self.滑块当前x,0,self.滑块宽度,self.高度)) # 滑块,根据值显示到相应位置
        else:
            pygame.draw.rect(self.控件surface,self.bg, (0,0,self.宽度,self.高度))                       # 滑块槽
            pygame.draw.rect(self.控件surface,self.滑块颜色, (self.滑块当前x,0,self.滑块宽度,self.高度))  # 滑块,根据值显示到相应位置
        pygame.draw.line(self.控件surface,self.滑块标线颜色,(self.滑块当前x+self.滑块起始x-1,0),\
                        (self.滑块当前x+self.滑块起始x-1,self.高度),2)                                   # 滑块中间的标识线
            
        if self.显示数据:
            if self.滑块当前x > self.宽度/2:
                self.写((f' {self.无限大提示} ' if self.实际值 == self.无限大值 else f' {self.实际值} '),2,(self.高度-self.fontsize)//2,self.fontsize,self.fg,bg=(255,0,0))                # 显示值
            else:
                self.写((f' {self.无限大提示} ' if self.实际值 == self.无限大值 else f' {self.实际值} '),self.宽度-2,(self.高度-self.fontsize)//2,self.fontsize,self.fg,'右',(255,0,0)) # 显示值
                
        self.screen.blit(self.控件surface, (self.坐标x,self.坐标y)) # 绘制
        return self.实际值
        
    def 写(self,string,x,y,fontsize,color,对齐方式='左',bg=None): 
        '''参数说明:(显示的内容,坐标x y,字体大小,字颜色,居中显示)  显示的内容:可以接收数字(int ,float)和字符类型(str)
        对齐方式:'左','中','右',默认为左对齐
        '''
        if isinstance(string,(int,float)):  # 判断数据类型
            string=str(string)              # 把数据转换成字符串
        cur_font = pygame.font.SysFont('simhei', fontsize)
        textSurf = cur_font.render(string[:self.宽度*4//fontsize-2], True,  color,bg)
        if 对齐方式=='左':
            TextRect = (x,y)
        elif 对齐方式=='中':
            rect=textSurf.get_rect()
            TextRect = (x-rect[2]/2,y)
        else: # 右对齐
            rect=textSurf.get_rect()
            TextRect = (x-rect[2],y)
            
        self.控件surface.blit(textSurf,TextRect)

def 滑动条演示():
    # 初始化 Pygame  
    pygame.init()  
    # 设置窗口尺寸  
    window_width = 400  
    window_height = 300  
    # 创建窗口  
    screen = pygame.display.set_mode((window_width, window_height))  

    # 初始化滑动条,并定义其相关量
    滑动条1 = 滑动条(screen,50, 50,280,20,100,0,255,1)
    滑动条2 = 滑动条(screen,50,150,280,20,0,100,30000,100,无限大=True)
    滑动条3 = 滑动条(screen,50,250,280,20,10,2,300,1,无限大=True,无限大值=0,无限大提示='系统最快',滑块颜色=(0,128,0),active_滑块颜色=(0,255,0))

    # 填充背景  
    screen.fill((255, 255, 255))  
    
    # 游戏主循环  
    while True:  
        for event in pygame.event.get():  
            if event.type == pygame.QUIT:  
                pygame.quit()  
                sys.exit()  
        
        # 更新滑动条并将其值返回到变量中
        a = 滑动条1.update()
        b = 滑动条2.update()
        c = 滑动条3.update()
        print('滑动条的值分别为:',a,b,c)
        # 更新显示  
        pygame.display.flip()

if __name__ == '__main__':
    滑动条演示()
    pygame.quit()

from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog from PySide6.QtGui import QPixmap, QImage from PySide6.QtCore import QTimer, Qt import sys import cv2 import os import pygame import tempfile from moviepy import VideoFileClip from video02_ui import Ui_MainWindow class VideoApp02(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # 初始化音频系统 pygame.mixer.init() # 连接控件信号 self.ui.openButton.clicked.connect(self.openVideo) self.ui.playButton.clicked.connect(self.toggle_play) self.ui.stopButton.clicked.connect(self.stop_video) self.ui.horizontalSlider.sliderPressed.connect(self.slider_pressed) self.ui.horizontalSlider.sliderReleased.connect(self.slider_released) self.ui.horizontalSlider.sliderMoved.connect(self.slider_moved) # 初始化变量 self.file_path = None self.clip = None self.frame_count = 0 self.current_frame = 0 self.is_playing = False self.is_slider_pressed = False self.temp_audio = None # 定时器设置 self.timer = QTimer(self) self.timer.timeout.connect(self.update_frame) def toggle_play(self): if not self.file_path: self.ui.statusbar.showMessage("请先打开视频文件!") return if self.is_playing: self.pause_video() else: self.start_playback() def start_playback(self): try: if not self.clip: self.init_video() # 确保音频已加载 if not pygame.mixer.music.get_busy(): if os.path.exists(self.temp_audio.name): pygame.mixer.music.load(self.temp_audio.name) else: raise FileNotFoundError("音频文件不存在") if self.current_frame >= self.frame_count: self.current_frame = 0 self.is_playing = True
最新发布
03-19
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘庆豪2007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值