news 2026/8/22 1:32:22

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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学习交流群】:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 16:23:14

SC4D20120D-JSM 碳化硅肖特基二极管

在新能源、工业控制等领域的技术迭代浪潮中&#xff0c;碳化硅&#xff08;SiC&#xff09;器件凭借其卓越的高频、高效、耐高温性能&#xff0c;成为破解传统硅基器件瓶颈的核心方案。杰盛微半导体&#xff08;JSMSEMI&#xff09;立足市场需求&#xff0c;重磅推出SC4D20120D…

作者头像 李华
网站建设 2026/8/21 19:15:38

SID310S/D/Q-10MHz, 低噪声, 轨至轨, CMOS 运算放大器替代SGM722

概述 General Description SID310S/D/Q是CMOS型、轨至轨输出/输出的电压反馈型运算放大器。可以支持1.7~5.5V的供电范围&#xff0c;每个通道仅消耗530μA的电流&#xff0c;拥有较低的失调电压和温漂。 该系列产品拥有10MHz的增益带宽积&#xff0c;外接500pF电容负载时也能保…

作者头像 李华
网站建设 2026/8/21 11:26:50

基于Django的旅游网站源码设计与文档

前言基于 Django 的旅游网站&#xff0c;直击 “旅游信息杂乱、行程规划繁琐、个性化推荐缺失” 的核心痛点&#xff0c;依托 Django 的 MVT 架构优势与 Python 的数据分析能力&#xff0c;构建 “目的地指南 智能行程 互动分享” 的一体化旅游服务平台。传统模式下&#xff…

作者头像 李华
网站建设 2026/8/21 20:24:41

ai搜索文献:高效获取学术资源的智能工具与应用指南

开题报告前那两个月&#xff0c;我电脑里塞满了乱七八糟的PDF&#xff0c;参考文献格式错得千奇百怪&#xff0c;导师一句“脉络不清”打回来三次。后来才发现&#xff0c;问题不是读得不够多&#xff0c;而是工具没用对。这三个工具帮我理清了思路&#xff0c;把一堆文献变成了…

作者头像 李华
网站建设 2026/8/21 12:40:04

深度强化学习的现状与展望

深度强化学习&#xff08;Deep Reinforcement Learning, DRL&#xff09;是深度学习与强化学习的融合&#xff0c;利用神经网络逼近策略或值函数&#xff0c;使智能体能在复杂环境中通过试错学习最优决策。自2013年DQN在Atari游戏中取得突破以来&#xff0c;DRL迅速发展&#x…

作者头像 李华