pyside6 控件二:自定义树控件

你的名字 2024-03-23 14:44 202阅读 0赞

目录

一、自定义控件(读者可直接Copy)

二、使用案例


一、自定义控件(读者可直接Copy)

  1. import os
  2. import platform
  3. from PySide6 import QtWidgets
  4. from PySide6.QtCore import QObject, Signal, Qt
  5. from PySide6.QtGui import QIcon
  6. from PySide6.QtWidgets import QWidget, QVBoxLayout, QTreeWidget, QApplication, QTreeWidgetItem
  7. class TreeWidgetItem:
  8. def __init__(self, id: any, parent_id: any, name: str, icon: QIcon = None, extend: object = None):
  9. """
  10. 菜单数据接口
  11. :param id: ID
  12. :param parent_id: 父ID
  13. :param name: 菜单名称
  14. :param icon: 图标
  15. :param extend: 扩展数据
  16. """
  17. self.id: any = id
  18. self.parent_id: any = parent_id
  19. self.name: str = name
  20. self.extend: object = extend
  21. # 实例化
  22. self.treeWidgetItem = QTreeWidgetItem([self.name])
  23. # 存储相关数据
  24. self.treeWidgetItem.setData(0, Qt.UserRole + 1, extend)
  25. self.treeWidgetItem.setIcon(0, QIcon(':/icons/default.png'))
  26. if icon is not None:
  27. self.treeWidgetItem.setIcon(0, icon)
  28. class ElTreeData(QObject):
  29. """
  30. Data Model
  31. """
  32. items_changed: Signal = Signal(str)
  33. styleSheet_changed: Signal = Signal(str)
  34. def __init__(self, items: list[TreeWidgetItem] = None, styleSheet: str = None):
  35. super(ElTreeData, self).__init__()
  36. # 定义数据
  37. self._items: list[TreeWidgetItem]
  38. self._styleSheet: str
  39. # 初始化数据
  40. self.items = items
  41. self.styleSheet = styleSheet
  42. @property
  43. def items(self):
  44. return self._items
  45. @items.setter
  46. def items(self, value):
  47. self._items = value
  48. # 数据改变时发出信号
  49. self.items_changed.emit(self.items)
  50. @property
  51. def styleSheet(self):
  52. return self._styleSheet
  53. @styleSheet.setter
  54. def styleSheet(self, value):
  55. self._styleSheet = value
  56. # 数据改变时发出信号
  57. self.styleSheet_changed.emit(self.styleSheet)
  58. """
  59. 初始化CSS文件位置
  60. """
  61. CSS_PATH = None
  62. if str(platform.system().lower()) == 'windows':
  63. path = __file__.replace(fr"\{os.path.basename(__file__)}", "").replace("\\\\", "\\")
  64. CSS_PATH = fr'{path}\el_tree.css'
  65. elif str(platform.system().lower()) == 'linux':
  66. path = __file__.replace(fr"/{os.path.basename(__file__)}", "").replace("//", "/")
  67. CSS_PATH = fr'{path}/el_tree.css'
  68. else:
  69. print(f"未知系统:{platform.system().lower()}")
  70. class ElTreeUi(object):
  71. """
  72. User Interface
  73. """
  74. def setupUi(self, window):
  75. with open(CSS_PATH, "r", encoding="UTF-8") as f:
  76. window.setStyleSheet(f.read())
  77. window.setWindowTitle("ElTree")
  78. window.setWindowIcon(QIcon(':/icons/add.png'))
  79. window.resize(40, 30)
  80. # 设置整个窗体的透明度
  81. window.setWindowOpacity(0.90) # 设置窗体透明度
  82. # 设置隐藏背景
  83. window.setAttribute(Qt.WA_TranslucentBackground)
  84. # 垂直布局
  85. self.layout = QVBoxLayout()
  86. # 设置边距为0
  87. self.layout.setContentsMargins(0, 0, 0, 0)
  88. window.setLayout(self.layout)
  89. self._tree = QTreeWidget()
  90. self._tree.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
  91. self.layout.addWidget(self._tree)
  92. class ElTree(QWidget, ElTreeUi):
  93. """
  94. Control
  95. """
  96. itemClicked: Signal = Signal(object)
  97. itemDoubleClicked: Signal = Signal(object)
  98. def __init__(self, treeData: ElTreeData, parent=None):
  99. super(ElTree, self).__init__(parent=parent)
  100. self.setupUi(self)
  101. self.data = treeData
  102. self.__bind()
  103. # 将按钮的点击信号绑定到当前类的点击信号
  104. self._tree.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
  105. self._tree.itemDoubleClicked.connect(lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
  106. self.__render_items(True)
  107. def __render_items(self, is_clear: bool):
  108. if is_clear:
  109. self._tree.clear()
  110. self._tree.setColumnCount(1)
  111. self._tree.setHeaderHidden(True)
  112. if self.data.items is not None:
  113. # 转为字典
  114. mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
  115. # 树容器
  116. treeWidgetItems: list[QTreeWidgetItem] = []
  117. for d in self.data.items:
  118. # 如果找不到父级项,则是根节点
  119. parent: TreeWidgetItem = mapping.get(d.parent_id)
  120. if parent is None:
  121. treeWidgetItems.append(d.treeWidgetItem)
  122. else:
  123. parent.treeWidgetItem.addChild(d.treeWidgetItem)
  124. # 挂载到树上
  125. self._tree.insertTopLevelItems(0, treeWidgetItems)
  126. def __bind(self):
  127. """
  128. 数据绑定到控件属性
  129. """
  130. pass

二、使用案例

  1. if __name__ == '__main__':
  2. """
  3. Test Demo
  4. """
  5. # 引入资源(这一步不能少!)
  6. from images.resources_rc import *
  7. app = QApplication([])
  8. button = ElTree(ElTreeData(items=[
  9. TreeWidgetItem(1, 0, "User", icon=QIcon(":/icons/add.png"), extend={'id': 1}),
  10. TreeWidgetItem(2, 1, "Child", icon=QIcon(":/icons/address.png"), extend={'id': 2}),
  11. TreeWidgetItem(3, 1, "Child", icon=QIcon(":/icons/code_generator.png"), extend={'id': 3}),
  12. TreeWidgetItem(4, 2, "Child", icon=QIcon(":/icons/linked.png"), extend={'id': 4}),
  13. TreeWidgetItem(5, 2, "Child", icon=QIcon(":/icons/template.png"), extend={'id': 5}),
  14. TreeWidgetItem(6, 5, "Child", icon=QIcon(":/icons/template_edit.png"), extend={'id': 6}),
  15. TreeWidgetItem(7, 5, "Child", extend={'id': 7}),
  16. TreeWidgetItem(8, 5, "Child", extend={'id': 8}),
  17. TreeWidgetItem(9, 8, "Child", extend={'id': 9}),
  18. ]))
  19. button.itemClicked.connect(lambda extend: print("单击->扩展数据为:", extend))
  20. button.itemDoubleClicked.connect(lambda extend: print("双击->扩展数据为:", extend))
  21. button.show()
  22. app.exec()

387d0e9b011447e5a9cb6867638ce9ec.png

发表评论

表情:
评论列表 (有 0 条评论,202人围观)

还没有评论,来说两句吧...

相关阅读