当前位置: 首页 > news >正文

tkinter绘制组件(51)——高级滑动条

tkinter绘制组件(51)高级滑动条

  • 引言
  • 中段滑动条
    • 禁用与激活
    • 获取值
    • 设置值
      • set(value)
      • select(num, send=True)
    • 例子
  • 双端滑动条
    • 禁用与激活
    • 获取值
    • 设置值
    • 例子
  • github项目
  • pip下载

引言

在tkinter绘制组件(15)——调节框_tkintertable-CSDN博客详细讲述了如何构造一个基础滑动条scalebar。这里在此基础上,继续实现:

  • 中段滑动条:以中间点为零点的滑动条;
  • 双端滑动条:用于范围选择的滑动条

Smart-Space/TinUISlider: TinUI高级滑动条中控件单独提供:

pip install tinuislider

中段滑动条

中段滑动条CenterSlider的零点位于数据中位,其余绘制逻辑与交互逻辑均与基础滑动条一致。

因此,构建上来说,貌似没什么好说的,唯一需要变更的点,就是所有位置计算均以控件中心为抽象锚点,这样能够省很多事,再配合上TinUI自身提供的位置对齐与区域对齐,很容易实现。

接下来直接看如何使用吧。

禁用与激活

和TinUI原生滑动条一致,CenterSlider提供disableactive_state两个方法用来对滑动条禁用和激活。

获取值

defget(self):"""获取当前选中的值"""returnself.data[self.nowselect]

设置值

set(value)

直接设置在data中的值。

select(num, send=True)

设置选项索引,send若为False,则不触发回调函数。

例子

fromtkinterimportTkfromtinuiimportBasicTinUI,ExpandPanel,VerticalPaneldefon_resize(event):rp.update_layout(10,10,event.width-10,event.height-10)r=Tk()ui=BasicTinUI(r)ui.pack(fill='both',expand=True)slider=CenterSlider(canvas=ui,pos=(0,100),width=200,data=range(-10,11),start=3,# start是索引,不是值,所以这里是选中数据中的第4项anchor="center",command=lambdav:print(f"Selected:{v}"))# 获取当前值val=slider.get()print(f"Current value:{val}")slider.set(5)# 设置选中值为 5print(f"Value after set:{slider.get()}")rp=ExpandPanel(ui)vp=VerticalPanel(ui)rp.set_child(vp)ep1=ExpandPanel(ui)vp.add_child(ep1,weight=1)ep1.set_child(slider.uid)ui.bind("<Configure>",on_resize)r.mainloop()


双端滑动条

双端滑动条RangeSlider用于选择数值上下限范围。

classRangeSlider:def__init__(self,canvas:BasicTinUI,pos:tuple,width=200,fg="#4554dc",activefg="#4554dc",bg="#868686",buttonbg="#ffffff",buttonoutline="#cccccc",data=(1,2,3,4,5),start_left=None,start_right=None,direction="x",anchor="nw",command=None,):#...

这里除了要限制滑块本身不能超过数值范围外,还有一个约束,就是左右滑块不能越位。

def_drag_left(self,event):pos=self._event_pos(event)right_limit=self._get_button_pos(self.right_button)ifself.direction=="x":pos=min(pos,right_limit)pos=max(pos,self.dash[0])# 不超过最左边界else:pos=max(pos,right_limit)pos=min(pos,self.dash[0])# 不超过最下边界self._move_button(self.left_button,pos)def_drag_right(self,event):pos=self._event_pos(event)left_limit=self._get_button_pos(self.left_button)ifself.direction=="x":pos=max(pos,left_limit)pos=min(pos,self.dash[-1])# 不超过最右边界else:pos=min(pos,left_limit)pos=max(pos,self.dash[-1])# 不超过最上边界self._move_button(self.right_button,pos)def_release_left(self,_):self.canvas.tag_raise(self.left_button,self.right_button)self.left_index=self._snap(self.left_button)self.left_index=min(self.left_index,self.right_index)self._update_buttons()self._update_active()self._send()def_release_right(self,_):self.canvas.tag_raise(self.right_button,self.left_button)self.right_index=self._snap(self.right_button)self.right_index=max(self.right_index,self.left_index)self._update_buttons()self._update_active()self._send()

其中其他工具函数,请参考代码库。看名字应该也能看出来在干嘛。

另外,当点击选择时,应当移动最近的滑块:

def_click_track(self,event):pos=self._event_pos(event)left_pos=self._get_button_pos(self.left_button)right_pos=self._get_button_pos(self.right_button)ifabs(pos-left_pos)<=abs(pos-right_pos):ifself.direction=="x":pos=min(pos,right_pos)else:pos=max(pos,right_pos)self._move_button(self.left_button,pos)self._release_left(None)else:ifself.direction=="x":pos=max(pos,left_pos)else:pos=min(pos,left_pos)self._move_button(self.right_button,pos)self._release_right(None)

禁用与激活

同上一个控件。

获取值

通过get获取(l_value, r_value)

设置值

通过set(left=None, right=None)设置值(注意,不是索引),若为None,则不变。

例子

defon_resize(event):rp.update_layout(10,10,event.width-10,event.height-10)r=Tk()ui=BasicTinUI(r)ui.pack(fill='both',expand=True)slider=CenterSlider(canvas=ui,pos=(0,100),width=200,data=range(-10,11),start=3,# start是索引,不是值,所以这里是选中数据中的第4项anchor="center",command=lambdav:print(f"Selected:{v}"))# 获取当前值val=slider.get()print(f"Current value:{val}")slider.set(5)# 设置选中值为 5print(f"Value after set:{slider.get()}")rp=ExpandPanel(ui)vp=VerticalPanel(ui)rp.set_child(vp)ep1=ExpandPanel(ui)vp.add_child(ep1,weight=1)ep1.set_child(slider.uid)ui.bind("<Configure>",on_resize)r.mainloop()


github项目

TinUI的github项目地址

pip下载

pipinstalltinui
http://www.jsqmd.com/news/520958/

相关文章:

  • Artisan咖啡烘焙软件:3大核心功能解密,从入门到精通的完整指南
  • TCN-GRU这个组合模型算是把时间序列预测的两个经典结构玩出了花——时间卷积负责抓局部特征,GRU来捕捉时序依赖关系。咱直接上代码看看核心部分怎么搭的
  • Whisper-large-v3在媒体行业的应用:智能字幕生成系统
  • Qwen3-0.6B-FP8部署避坑指南:新手常见问题与解决方案
  • 嵌入式系统可靠性设计七项工程实践
  • Android AOA协议嵌入式实现:裸机/RTOS兼容的USB配件模式库
  • Vibe Coding技巧-用 AI 写代码越修 Bug 越崩溃?这四步法帮你告别来回拉扯
  • 爆火全球的“小龙虾“OpenClaw:你的下一个AI管家,还是安全定时炸弹?
  • Needleman-Wunsch算法优化指南:如何用非递归方法解决多路径回溯问题?
  • STM32F103 8位并行TFT驱动库深度解析
  • SW - SW2025自带帮助文件的位置和含义
  • EcomGPT-7B模型对抗攻击与鲁棒性增强实践
  • STLink v1.8.0版本升级技术指南:从架构演进到实践落地
  • FXOS8700Q嵌入式驱动开发:9轴IMU寄存器级控制与FreeRTOS集成
  • Ubuntu下使用Docker部署Milvus及可视化工具实战指南
  • DeepSeek-R1加速秘籍:无需复杂操作,几个参数让CPU推理更快
  • SF6微水密传感器接头M12-5芯金属波纹管连接器
  • Xshell密钥免密登录Linux服务器保姆级教程(含常见问题排查)
  • GTE文本向量中文大模型保姆级教程:从部署到旅游评论分析全流程
  • 技能智能体开发:构建基于TranslateGemma的翻译Agent
  • 2603,系统调用
  • 告别断网烦恼!Android智能家居场景下的Wi-Fi双连接避坑指南
  • 突破BIM协作瓶颈:IfcOpenShell开源引擎的技术革新与实践指南
  • 告别电源纹波焦虑:深入拆解一个手机充电器里的BUCK电路,看闭环控制如何“稳住”输出电压
  • Z-Image-Turbo-辉夜巫女应用场景:快速生成同人创作、角色设定图,二次元创作者必备
  • nRF51+PAJ7620手势识别固件库设计与低功耗实现
  • 简单三步:用Fish Speech 1.5实现语音评测功能
  • GriddyCode使用指南:从入门到精通的视觉编码之旅
  • Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF镜像快速部署:手把手教你玩转AI文本生成
  • 开发地图应用效率提升50%,百度地图Map Skills解决AI编码落地难题