203 lines
6.7 KiB
Python
203 lines
6.7 KiB
Python
![]() |
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())
|