brisonus_app_eq/widget_file_list/QtWidgetsApplication4.cpp

304 lines
8.9 KiB
C++
Raw Normal View History

2025-02-16 21:24:51 +08:00
#include "QtWidgetsApplication4.h"
#include <QPainter>
#include <QApplication>
#include <QVBoxLayout>
#include <QMenu>
#include <QDate>
#include <QProcess>
#include <QDir>
#include <QDebug>
//#include <QTextCodec>
#include <QFileInfo>
CardData::CardData(const QString& name, const QString& date, const QString& description)
: name(name), date(date), description(description), activated(false)
{
}
CardItemDelegate::CardItemDelegate(QObject* parent)
: QStyledItemDelegate(parent)
{
}
void CardItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
painter->setRenderHint(QPainter::Antialiasing);
painter->save();
// 获取数据
CardData data = index.data(Qt::UserRole).value<CardData>();
// 绘制卡片背景
QRect rect = option.rect;
rect.adjust(8, 4, -8, -4);
// 创建圆角路径
QPainterPath path;
path.addRoundedRect(rect, 8, 8);
// 绘制阴影
QColor shadowColor(0, 0, 0, 30);
for (int i = 0; i < 5; ++i) {
QRect shadowRect = rect.adjusted(0, i, 0, i);
QPainterPath shadowPath;
shadowPath.addRoundedRect(shadowRect, 8, 8);
painter->fillPath(shadowPath, shadowColor);
}
// 绘制卡片背景
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
if (data.activated) {
gradient.setColorAt(0, QColor(40, 70, 45));
gradient.setColorAt(1, QColor(45, 80, 50));
painter->fillPath(path, gradient);
painter->setPen(QPen(QColor(60, 180, 90), 2));
}
else if (option.state & QStyle::State_Selected) {
gradient.setColorAt(0, QColor(45, 45, 55));
gradient.setColorAt(1, QColor(55, 55, 65));
painter->fillPath(path, gradient);
painter->setPen(QPen(QColor(70, 130, 180), 2));
}
else {
painter->fillPath(path, QColor(35, 35, 40));
painter->setPen(QPen(QColor(60, 60, 65)));
}
painter->drawPath(path);
// 设置字体
QFont nameFont("Microsoft YaHei", 10);
nameFont.setBold(true);
QFont normalFont("Microsoft YaHei", 9);
// 计算文本区域
int padding = 15;
QRect nameRect = rect.adjusted(padding, padding, -padding, 0);
nameRect.setHeight(25);
QRect dateRect = nameRect;
dateRect.translate(0, nameRect.height());
QRect descRect = dateRect;
descRect.translate(0, dateRect.height());
descRect.setHeight(40);
// 绘制文本
painter->setFont(nameFont);
painter->setPen(Qt::white);
painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, data.name);
painter->setFont(normalFont);
painter->setPen(QColor(180, 180, 180));
painter->drawText(dateRect, Qt::AlignLeft | Qt::AlignVCenter, data.date);
painter->setPen(QColor(160, 160, 160));
painter->drawText(descRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap,
data.description);
painter->restore();
}
QSize CardItemDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
return QSize(380, 130);
}
MainWindow::MainWindow(QWidget* parent)
: QWidget(parent)
{
setupUI();
setupStyle();
// 添加示例数据
for (int i = 1; i <= 10; ++i) {
CardData data(
QString("项目 %1").arg(i),
QDate::currentDate().toString("yyyy-MM-dd"),
QString("这是项目 %1 的详细描述信息,可以包含多行文本内容。这是一个较长的描述,用于测试换行效果。").arg(i)
);
addCardItem(data);
}
}
void MainWindow::setupUI()
{
setWindowTitle(tr("卡片列表示例"));
resize(400, 600);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(10, 10, 10, 10);
layout->setSpacing(0);
listWidget = new QListWidget(this);
listWidget->setSpacing(10);
listWidget->setResizeMode(QListWidget::Adjust);
listWidget->setUniformItemSizes(false);
listWidget->setViewMode(QListWidget::ListMode);
listWidget->setVerticalScrollMode(QListWidget::ScrollPerPixel);
listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
CardItemDelegate* delegate = new CardItemDelegate(listWidget);
listWidget->setItemDelegate(delegate);
// 连接信号
connect(listWidget, &QListWidget::itemDoubleClicked,
this, &MainWindow::onItemDoubleClicked);
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(listWidget, &QListWidget::customContextMenuRequested,
this, &MainWindow::showContextMenu);
layout->addWidget(listWidget);
}
void MainWindow::setupStyle()
{
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;"
"}"
);
}
void MainWindow::addCardItem(const CardData& data)
{
QListWidgetItem* item = new QListWidgetItem(listWidget);
item->setData(Qt::UserRole, QVariant::fromValue(data));
item->setSizeHint(QSize(380, 120));
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
void MainWindow::onItemDoubleClicked(QListWidgetItem* item)
{
// 先将所有项目设置为未激活状态
for (int row = 0; row < listWidget->count(); ++row) {
QListWidgetItem* currentItem = listWidget->item(row);
CardData data = currentItem->data(Qt::UserRole).value<CardData>();
data.activated = false;
currentItem->setData(Qt::UserRole, QVariant::fromValue(data));
}
// 设置当前点击项目为激活状态
CardData data = item->data(Qt::UserRole).value<CardData>();
data.activated = true;
item->setData(Qt::UserRole, QVariant::fromValue(data));
listWidget->viewport()->update();
}
void MainWindow::showContextMenu(const QPoint& pos)
{
QListWidgetItem* item = listWidget->itemAt(pos);
if (!item) return;
QMenu menu(this);
QAction* sendAction = menu.addAction(tr("发送到设备"));
menu.addSeparator();
QAction* editAction = menu.addAction(tr("修改"));
QAction* deleteAction = menu.addAction(tr("删除"));
menu.addSeparator();
QAction* showInExplorerAction = menu.addAction(tr("在资源管理器中显示"));
// 设置图标
sendAction->setIcon(QIcon::fromTheme("document-send"));
editAction->setIcon(QIcon::fromTheme("document-edit"));
deleteAction->setIcon(QIcon::fromTheme("document-delete"));
showInExplorerAction->setIcon(QIcon::fromTheme("folder"));
QAction* action = menu.exec(listWidget->viewport()->mapToGlobal(pos));
if (!action) return;
if (action == sendAction)
sendToDevice(item);
else if (action == editAction)
editItem(item);
else if (action == deleteAction)
deleteItem(item);
else if (action == showInExplorerAction)
showInExplorer(item);
}
void MainWindow::sendToDevice(QListWidgetItem* item)
{
CardData data = item->data(Qt::UserRole).value<CardData>();
qDebug() << "发送到设备:" << data.name;
}
void MainWindow::editItem(QListWidgetItem* item)
{
CardData data = item->data(Qt::UserRole).value<CardData>();
qDebug() << "编辑项目:" << data.name;
}
void MainWindow::deleteItem(QListWidgetItem* item)
{
int row = listWidget->row(item);
delete listWidget->takeItem(row);
}
void MainWindow::showInExplorer(QListWidgetItem* item)
{
QString path = QDir::currentPath();
#ifdef Q_OS_WIN
QProcess::startDetached("explorer.exe", { "/select,", QDir::toNativeSeparators(path) });
#elif defined(Q_OS_MAC)
QProcess::startDetached("open", { "-R", path });
#else
QProcess::startDetached("xdg-open", { QFileInfo(path).path() });
#endif
}