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

PySide6 自定义侧边栏 实现思路与代码详解

PySide6 自定义侧边栏 实现思路与代码详解

PySide6虽然得益于Qt框架的强大与Python语法的快速开发,但是默认提供的主题不符合现代UI的省美!比如:侧边栏一般也叫导航栏(更多是手机平板的等设备)。

写在前边

笔者使用的是LinuxGnome桌面系统,其他显示效果请自行尝试!

为了更方便的描述,这里分为如下俩中情况:

  1. 默认展开 => 切换后先收缩
  2. 默认收缩 => 切换后先放大

效果演示


默认展开

注意:

  • 紫色为:QFrame嵌套QVboxLayout是主窗口
  • 绿色为:QFrame嵌套QVboxLayout是侧边栏(父类为主窗口的QFrame)
实现思路

显示与隐藏核心:

  • 默认展开:QFrame设置最大与最小宽度为155
  • 切换:重新设置QFrame的最小宽度

温馨提示:
setFixedWidth<=>setMinimumWidth+setMaximumWidth
选择QFrame一是参考Qt Designer,二是继承QWidget更好的设置 属性

核心代码解读
deftoggle_sidebar(self):"""show or hide toggle button text"""self.anim=QPropertyAnimation(self.__sidebar_frame,b"minimumWidth")self.anim.stop()ifself.__sidebar_visible==False:# hide: right to leftself.anim.setStartValue(self.__sidebar_frame.width())self.anim.setEndValue(40)else:# show: left to rightself.anim.setStartValue(self.__sidebar_frame.width())self.anim.setEndValue(155)self.__sidebar_frame.setFixedWidth(40)self.anim.setEasingCurve(QEasingCurve.Type.InOutQuad)self.anim.setDuration(500)self.anim.start()self.__sidebar_visible=notself.__sidebar_visible

重点如下:

  1. QPropertyAnimation:实现显示与隐藏的动画效果;官方文档
  2. QEasingCurve:使得动画更丝滑;官方文档
  3. setDuration:设置动画的持续时间;官方文档

⚠️注意

  1. 取消self.__sidebar_frame.setFixedWidth(40)将无法正常收缩
  2. 改变整体布局为QHBoxLayout,展开与收缩就会从QFrame中心垂线收缩展开

完整代码:

#hide_sidebar.pyimportsysfromPySide6.QtWidgetsimport(QWidget,QFrame,QVBoxLayout,QPushButton,QApplication)fromPySide6.QtCoreimportQPropertyAnimation,QEasingCurveclassQCustomeWidget(QWidget):"""Custome sidebar """def__init__(self):self.__sidebar_visible=Falsesuper().__init__()self.__setup_ui()self.__setup_event_handel()def__setup_ui(self):# widget sizeself.setFixedSize(400,300)# global layout use framelayout then vboxlayoutself.__global_frame=QFrame(self)self.__global_frame.setContentsMargins(0,0,0,0)self.__global_layout=QVBoxLayout(self.__global_frame)self.__global_layout.setSpacing(0)self.__global_layout.setContentsMargins(0,0,0,0)# sidebar frame framelayoutself.__sidebar_frame=QFrame(self.__global_frame)self.__sidebar_layout=QVBoxLayout(self.__sidebar_frame)self.__sidebar_frame.setLayout(self.__sidebar_layout)self.__sidebar_frame.setContentsMargins(0,0,0,0)self.__sidebar_layout.setContentsMargins(0,0,0,0)self.__sidebar_layout.setSpacing(0)# form sizeself.__sidebar_frame.setFixedSize(155,self.height())self.__sidebar_frame.setStyleSheet("background-color:grey;")# toggle and home buttonself.__toggle_btn=QPushButton('show: button text',self.__sidebar_frame)self.__toggle_btn.setStyleSheet(".QPushButton {background-color: rgb(56, 56, 60);text-align: left;}")self.__home_btn=QPushButton('home: button text',self.__sidebar_frame)self.__home_btn.setStyleSheet(".QPushButton {background-color: rgb(56, 56, 60);text-align: left;}")# add buttonself.__sidebar_layout.addWidget(self.__toggle_btn)self.__sidebar_layout.addWidget(self.__home_btn)# add Widgetself.__global_layout.addWidget(self.__sidebar_frame)def__setup_event_handel(self):self.__toggle_btn.clicked.connect(self.toggle_sidebar)deftoggle_sidebar(self):"""show or hide toggle button text"""self.anim=QPropertyAnimation(self.__sidebar_frame,b"minimumWidth")self.anim.stop()ifself.__sidebar_visible==False:# hide: right to leftself.anim.setStartValue(self.__sidebar_frame.width())self.anim.setEndValue(40)else:# show: left to rightself.anim.setStartValue(self.__sidebar_frame.width())self.anim.setEndValue(155)self.__sidebar_frame.setFixedWidth(40)self.anim.setEasingCurve(QEasingCurve.Type.OutQuad)self.anim.setDuration(500)self.anim.start()self.__sidebar_visible=notself.__sidebar_visibledefmain():app=QApplication([])sidebar=QCustomeWidget()sidebar.show()sys.exit(app.exec())if__name__=="__main__":main()

默认隐藏

注意:

  • 紫色为:QFrame嵌套QVboxLayoutQHboxLayout是主窗口
  • 绿色为:QFrame嵌套QVboxLayout是侧边栏(父类为主窗口的QFrame)
实现思路

与默认展开不同的是:

  • 右侧需要控件用于占用剩余的空间.
完整代码
#show_sidebar.pyimportsysfromPySide6.QtWidgetsimport(QWidget,QFrame,QHBoxLayout,QVBoxLayout,QLabel,QPushButton,QApplication)fromPySide6.QtCoreimport(QPropertyAnimation,QEasingCurve)classQCustomeSideBar(QWidget):"""Custome sidebar """def__init__(self):self.__sidebar_visible=Falsesuper().__init__()self.__setup_ui()self.__setup_event_handel()def__setup_ui(self):# widget sizeself.setFixedSize(400,300)# global layout use framelayout then vboxlayoutself.__global_frame=QFrame(self)self.__global_frame.setContentsMargins(0,0,0,0)self.__global_layout=QVBoxLayout(self.__global_frame)# or use# self.__global_layout = QHBoxLayout(self.__global_frame)self.__global_layout.setSpacing(0)self.__global_layout.setContentsMargins(0,0,0,0)# content and sidebar frame framelayoutself.__sidebar_frame=QFrame(self.__global_frame)self.__sidebar_layout=QVBoxLayout(self.__sidebar_frame)self.__sidebar_frame.setLayout(self.__sidebar_layout)self.__sidebar_frame.setContentsMargins(0,0,0,0)self.__sidebar_layout.setContentsMargins(0,0,0,0)self.__sidebar_layout.setSpacing(0)# form sizeself.__sidebar_frame.setFixedSize(40,self.height())self.__sidebar_frame.setStyleSheet("background-color:grey;")# toggle and home buttonself.__toggle_btn=QPushButton('show: button text',self.__sidebar_frame)self.__toggle_btn.setStyleSheet(".QPushButton {background-color: rgb(56, 56, 60);text-align: left;}")self.__home_btn=QPushButton('home: button text',self.__sidebar_frame)self.__home_btn.setStyleSheet(".QPushButton {background-color: rgb(56, 56, 60);text-align: left;}")# add buttonself.__sidebar_layout.addWidget(self.__toggle_btn)self.__sidebar_layout.addWidget(self.__home_btn)# add Widgetself.__global_layout.addWidget(self.__sidebar_frame)self.__content_button=QLabel("text")self.__content_button.setStyleSheet("text-align: right; margin-left:115px;")self.__global_layout.addWidget(self.__content_button)def__setup_event_handel(self):self.__toggle_btn.clicked.connect(self.toggle_sidebar)deftoggle_sidebar(self):"""show or hide toggle button text"""self.anim=QPropertyAnimation(self.__sidebar_frame,b"minimumWidth",self.__global_frame)self.anim.stop()ifself.__sidebar_visible==False:# show: left to rightself.anim.setStartValue(self.__sidebar_frame.width())self.anim.setEndValue(155)else:# hide: right to leftself.anim.setStartValue(self.__sidebar_frame.width())self.anim.setEndValue(40)self.anim.setEasingCurve(QEasingCurve.Type.InOutQuad)self.anim.setDuration(500)self.anim.start()self.__sidebar_visible=notself.__sidebar_visibledefmain():app=QApplication([])sidebar=QCustomeSideBar()sidebar.show()sys.exit(app.exec())if__name__=="__main__":main()
一起学习与探讨

点击链接加入群聊【PySide6学习交流群】:

http://www.cnnetsun.cn/news/24941.html

相关文章:

  • 【压力】矩阵-断裂-瓦格压力瞬态曲线模型和类型曲线【含Matlab源码 14685期】
  • Swagger UI高效调试实战:从入门到精通的全链路解决方案
  • 数字员工是什么?熊猫智汇在提升AI销售工具效率上的优势是什么?
  • 文献查询:高效获取与管理学术资源的实用指南
  • VLC播放器UOS ARM版离线部署指南
  • 税局正在调研“赛维模式”?广东多地卖家收到通知
  • OpenPose Editor完整教程:3步实现精准AI姿势控制
  • 学生成绩查询管理系统,AI智能评语与数据分析工具
  • WebAssembly反编译实战:从二进制迷雾到清晰代码的蜕变之旅
  • RankMixer:工业级推荐系统中排序模型的规模化扩展
  • 【SSM网上跳蚤市场】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
  • Qwen3-4B-FP8模型:5分钟轻松上手的AI开发新选择
  • Version-Fox终极插件管理指南:从零开始掌握多版本控制
  • Cloudpods终极指南:简单快速实现多云管理自动化
  • 极速AI助手快速接入腾讯混元大模型教程
  • 淘宝直播数据抓取终极指南:快速掌握实时监控技巧
  • Tomcat跨域配置终极指南:5分钟解决CORS问题
  • JAVA中如何操作文件
  • Tauri WebAssembly实战指南:5个技巧让应用性能飙升300%
  • Obsidian日历插件终极指南:5分钟打造高效笔记管理系统
  • 英伟达奖学金半数以上都是华人?
  • ManiSkill机器人仿真环境完全使用指南
  • GLM语言模型深度解析:从技术原理到实战应用的进阶指南
  • RookieAI_yolov8:2025年AI游戏辅助的完整解决方案与性能优化指南
  • 海量数据中找出最大的前100个(find_topk)最小堆算法
  • Claude Code Router多模型集成实战:打造智能开发工作流
  • 水稻病害检测(YOLO数据集,多分类,稻瘟病、纹枯病、褐斑病、枯心病、霜霉病、水稻细菌性条纹斑病、稻苞虫)
  • ABB机器人省气装置在薄板焊接中的实际效果
  • 京东Java面试被问:ZGC的染色指针如何实现?内存屏障如何处理?
  • 硬件 - 高速协议设计整合