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())