pyside6 控件二:自定义树控件
目录
一、自定义控件(读者可直接Copy)
二、使用案例
一、自定义控件(读者可直接Copy)
import os
import platform
from PySide6 import QtWidgets
from PySide6.QtCore import QObject, Signal, Qt
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QWidget, QVBoxLayout, QTreeWidget, QApplication, QTreeWidgetItem
class TreeWidgetItem:
def __init__(self, id: any, parent_id: any, name: str, icon: QIcon = None, extend: object = None):
"""
菜单数据接口
:param id: ID
:param parent_id: 父ID
:param name: 菜单名称
:param icon: 图标
:param extend: 扩展数据
"""
self.id: any = id
self.parent_id: any = parent_id
self.name: str = name
self.extend: object = extend
# 实例化
self.treeWidgetItem = QTreeWidgetItem([self.name])
# 存储相关数据
self.treeWidgetItem.setData(0, Qt.UserRole + 1, extend)
self.treeWidgetItem.setIcon(0, QIcon(':/icons/default.png'))
if icon is not None:
self.treeWidgetItem.setIcon(0, icon)
class ElTreeData(QObject):
"""
Data Model
"""
items_changed: Signal = Signal(str)
styleSheet_changed: Signal = Signal(str)
def __init__(self, items: list[TreeWidgetItem] = None, styleSheet: str = None):
super(ElTreeData, self).__init__()
# 定义数据
self._items: list[TreeWidgetItem]
self._styleSheet: str
# 初始化数据
self.items = items
self.styleSheet = styleSheet
@property
def items(self):
return self._items
@items.setter
def items(self, value):
self._items = value
# 数据改变时发出信号
self.items_changed.emit(self.items)
@property
def styleSheet(self):
return self._styleSheet
@styleSheet.setter
def styleSheet(self, value):
self._styleSheet = value
# 数据改变时发出信号
self.styleSheet_changed.emit(self.styleSheet)
"""
初始化CSS文件位置
"""
CSS_PATH = None
if str(platform.system().lower()) == 'windows':
path = __file__.replace(fr"\{os.path.basename(__file__)}", "").replace("\\\\", "\\")
CSS_PATH = fr'{path}\el_tree.css'
elif str(platform.system().lower()) == 'linux':
path = __file__.replace(fr"/{os.path.basename(__file__)}", "").replace("//", "/")
CSS_PATH = fr'{path}/el_tree.css'
else:
print(f"未知系统:{platform.system().lower()}")
class ElTreeUi(object):
"""
User Interface
"""
def setupUi(self, window):
with open(CSS_PATH, "r", encoding="UTF-8") as f:
window.setStyleSheet(f.read())
window.setWindowTitle("ElTree")
window.setWindowIcon(QIcon(':/icons/add.png'))
window.resize(40, 30)
# 设置整个窗体的透明度
window.setWindowOpacity(0.90) # 设置窗体透明度
# 设置隐藏背景
window.setAttribute(Qt.WA_TranslucentBackground)
# 垂直布局
self.layout = QVBoxLayout()
# 设置边距为0
self.layout.setContentsMargins(0, 0, 0, 0)
window.setLayout(self.layout)
self._tree = QTreeWidget()
self._tree.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
self.layout.addWidget(self._tree)
class ElTree(QWidget, ElTreeUi):
"""
Control
"""
itemClicked: Signal = Signal(object)
itemDoubleClicked: Signal = Signal(object)
def __init__(self, treeData: ElTreeData, parent=None):
super(ElTree, self).__init__(parent=parent)
self.setupUi(self)
self.data = treeData
self.__bind()
# 将按钮的点击信号绑定到当前类的点击信号
self._tree.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
self._tree.itemDoubleClicked.connect(lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
self.__render_items(True)
def __render_items(self, is_clear: bool):
if is_clear:
self._tree.clear()
self._tree.setColumnCount(1)
self._tree.setHeaderHidden(True)
if self.data.items is not None:
# 转为字典
mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
# 树容器
treeWidgetItems: list[QTreeWidgetItem] = []
for d in self.data.items:
# 如果找不到父级项,则是根节点
parent: TreeWidgetItem = mapping.get(d.parent_id)
if parent is None:
treeWidgetItems.append(d.treeWidgetItem)
else:
parent.treeWidgetItem.addChild(d.treeWidgetItem)
# 挂载到树上
self._tree.insertTopLevelItems(0, treeWidgetItems)
def __bind(self):
"""
数据绑定到控件属性
"""
pass
二、使用案例
if __name__ == '__main__':
"""
Test Demo
"""
# 引入资源(这一步不能少!)
from images.resources_rc import *
app = QApplication([])
button = ElTree(ElTreeData(items=[
TreeWidgetItem(1, 0, "User", icon=QIcon(":/icons/add.png"), extend={'id': 1}),
TreeWidgetItem(2, 1, "Child", icon=QIcon(":/icons/address.png"), extend={'id': 2}),
TreeWidgetItem(3, 1, "Child", icon=QIcon(":/icons/code_generator.png"), extend={'id': 3}),
TreeWidgetItem(4, 2, "Child", icon=QIcon(":/icons/linked.png"), extend={'id': 4}),
TreeWidgetItem(5, 2, "Child", icon=QIcon(":/icons/template.png"), extend={'id': 5}),
TreeWidgetItem(6, 5, "Child", icon=QIcon(":/icons/template_edit.png"), extend={'id': 6}),
TreeWidgetItem(7, 5, "Child", extend={'id': 7}),
TreeWidgetItem(8, 5, "Child", extend={'id': 8}),
TreeWidgetItem(9, 8, "Child", extend={'id': 9}),
]))
button.itemClicked.connect(lambda extend: print("单击->扩展数据为:", extend))
button.itemDoubleClicked.connect(lambda extend: print("双击->扩展数据为:", extend))
button.show()
app.exec()
还没有评论,来说两句吧...