brisonus_app_eq/component/widget_card/widget_card.py

203 lines
6.7 KiB
Python
Raw Normal View History

2025-02-18 22:05:52 +08:00
from PySide6.QtWidgets import (QWidget, QListWidget, QStyledItemDelegate,
QApplication, QVBoxLayout, QMenu, QListWidgetItem,
QStyle)
from PySide6.QtCore import Qt, QSize, QRect, QPoint
from PySide6.QtGui import (QPainter, QPainterPath, QColor, QLinearGradient,
QPen, QFont, QIcon)
from component.widget_card.ui_widget_card import CardItemDelegate
from dataclasses import dataclass
import sys
from datetime import date
import os
import subprocess
@dataclass
class CardData:
name: str
date: str
description: str
activated: bool = False
class Widget_Card(QWidget):
def __init__(self):
super().__init__()
self.setup_ui()
self.setup_style()
def setup_ui(self):
self.setWindowTitle("卡片列表示例")
self.resize(400, 600)
layout = QVBoxLayout(self)
layout.setContentsMargins(10, 10, 10, 10)
layout.setSpacing(0)
self.list_widget = QListWidget(self)
self.list_widget.setSpacing(10)
self.list_widget.setResizeMode(QListWidget.ResizeMode.Adjust)
self.list_widget.setUniformItemSizes(False)
self.list_widget.setViewMode(QListWidget.ViewMode.ListMode)
self.list_widget.setVerticalScrollMode(QListWidget.ScrollMode.ScrollPerPixel)
self.list_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
delegate = CardItemDelegate(self.list_widget)
self.list_widget.setItemDelegate(delegate)
# 连接信号
self.list_widget.itemDoubleClicked.connect(self.on_item_double_clicked)
self.list_widget.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.list_widget.customContextMenuRequested.connect(self.show_context_menu)
layout.addWidget(self.list_widget)
def setup_style(self):
self.setStyleSheet("""
QWidget {
background-color: #1e1e1e;
}
QListWidget {
background-color: #1e1e1e;
border: none;
outline: none;
}
QListWidget::item {
background-color: transparent;
padding: 4px;
}
QListWidget::item:selected {
background-color: transparent;
}
QScrollBar:vertical {
border: none;
background: #1e1e1e;
width: 8px;
margin: 0px;
}
QScrollBar::handle:vertical {
background: #404040;
min-height: 20px;
border-radius: 4px;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0px;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
background: none;
}
QMenu {
background-color: #2d2d2d;
border: 1px solid #404040;
padding: 5px;
}
QMenu::item {
background-color: transparent;
padding: 6px 25px;
border-radius: 4px;
color: #ffffff;
}
QMenu::item:selected {
background-color: #404040;
}
QMenu::separator {
height: 1px;
background: #404040;
margin: 5px 0px;
}
""")
def add_card_item(self, data: CardData):
item = QListWidgetItem(self.list_widget)
item.setData(Qt.ItemDataRole.UserRole, data)
item.setSizeHint(QSize(380, 120))
item.setFlags(Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable)
def on_item_double_clicked(self, item):
# 先将所有项目设置为未激活状态
for row in range(self.list_widget.count()):
current_item = self.list_widget.item(row)
data = current_item.data(Qt.ItemDataRole.UserRole)
data.activated = False
current_item.setData(Qt.ItemDataRole.UserRole, data)
# 设置当前点击项目为激活状态
data = item.data(Qt.ItemDataRole.UserRole)
data.activated = True
item.setData(Qt.ItemDataRole.UserRole, data)
self.list_widget.viewport().update()
def show_context_menu(self, pos: QPoint):
item = self.list_widget.itemAt(pos)
if not item:
return
menu = QMenu(self)
send_action = menu.addAction("发送到设备")
menu.addSeparator()
edit_action = menu.addAction("修改")
delete_action = menu.addAction("删除")
menu.addSeparator()
show_in_explorer_action = menu.addAction("在资源管理器中显示")
# 设置图标
send_action.setIcon(QIcon.fromTheme("document-send"))
edit_action.setIcon(QIcon.fromTheme("document-edit"))
delete_action.setIcon(QIcon.fromTheme("document-delete"))
show_in_explorer_action.setIcon(QIcon.fromTheme("folder"))
action = menu.exec(self.list_widget.viewport().mapToGlobal(pos))
if not action:
return
if action == send_action:
self.send_to_device(item)
elif action == edit_action:
self.edit_item(item)
elif action == delete_action:
self.delete_item(item)
elif action == show_in_explorer_action:
self.show_in_explorer(item)
def send_to_device(self, item):
data = item.data(Qt.ItemDataRole.UserRole)
print(f"发送到设备: {data.name}")
def edit_item(self, item):
data = item.data(Qt.ItemDataRole.UserRole)
print(f"编辑项目: {data.name}")
def delete_item(self, item):
row = self.list_widget.row(item)
self.list_widget.takeItem(row)
def show_in_explorer(self, item):
path = os.getcwd()
if sys.platform == 'win32':
subprocess.run(['explorer', '/select,', os.path.normpath(path)])
elif sys.platform == 'darwin':
subprocess.run(['open', '-R', path])
else:
subprocess.run(['xdg-open', os.path.dirname(path)])
if __name__ == '__main__':
app = QApplication(sys.argv)
# 设置字体
font = QFont("Microsoft YaHei", 9)
app.setFont(font)
window = Widget_Card()
# 添加示例数据
for i in range(1, 11):
data = CardData(
name=f"项目 {i}",
date=date.today().strftime("%Y-%m-%d"),
description=f"这是项目 {i} 的详细描述信息,可以包含多行文本内容。这是一个较长的描述,用于测试换行效果。"
)
window.add_card_item(data)
window.show()
sys.exit(app.exec())