180 lines
5.6 KiB
C++
180 lines
5.6 KiB
C++
|
|
#include "ImageTileWidget.h"
|
|||
|
|
#include <QPainter>
|
|||
|
|
#include <QMouseEvent>
|
|||
|
|
#include <QFileInfo>
|
|||
|
|
#include <QLabel>
|
|||
|
|
#include <QVBoxLayout>
|
|||
|
|
#include <QHBoxLayout>
|
|||
|
|
#include <QFontMetrics>
|
|||
|
|
#include <QStyleOption>
|
|||
|
|
#include <QImageReader>
|
|||
|
|
|
|||
|
|
ImageTileWidget::ImageTileWidget(QWidget* parent)
|
|||
|
|
: QWidget(parent) {
|
|||
|
|
setMinimumSize(120, 120);
|
|||
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|||
|
|
|
|||
|
|
// 创建缩小按钮
|
|||
|
|
m_shrinkButton = new QPushButton("×", this);
|
|||
|
|
m_shrinkButton->setFixedSize(24, 24);
|
|||
|
|
m_shrinkButton->setStyleSheet(
|
|||
|
|
"QPushButton {"
|
|||
|
|
" background-color: #ff4444;"
|
|||
|
|
" color: white;"
|
|||
|
|
" border: none;"
|
|||
|
|
" border-radius: 12px;"
|
|||
|
|
" font-weight: bold;"
|
|||
|
|
" font-size: 14px;"
|
|||
|
|
"}"
|
|||
|
|
"QPushButton:hover {"
|
|||
|
|
" background-color: #cc0000;"
|
|||
|
|
"}"
|
|||
|
|
);
|
|||
|
|
m_shrinkButton->hide();
|
|||
|
|
|
|||
|
|
connect(m_shrinkButton, &QPushButton::clicked, this, [this]() {
|
|||
|
|
emit shrinkRequested();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::setImagePath(const QString& path) {
|
|||
|
|
m_path = path;
|
|||
|
|
m_pix = QPixmap(path);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::setImage(const QImage& image) {
|
|||
|
|
m_pix = QPixmap::fromImage(image);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::setSelected(bool sel) {
|
|||
|
|
if (m_selected == sel) return;
|
|||
|
|
m_selected = sel;
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::setExpanded(bool expanded) {
|
|||
|
|
if (m_expanded == expanded) return;
|
|||
|
|
m_expanded = expanded;
|
|||
|
|
m_shrinkButton->setVisible(expanded);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QSize ImageTileWidget::sizeHint() const {
|
|||
|
|
if (m_expanded) {
|
|||
|
|
// 展开时使用父控件的大小或默认大小
|
|||
|
|
if (parentWidget()) {
|
|||
|
|
return parentWidget()->size();
|
|||
|
|
}
|
|||
|
|
return QSize(600, 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 非展开模式下,返回当前控件大小以支持动态缩放
|
|||
|
|
return size();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::paintEvent(QPaintEvent*) {
|
|||
|
|
QPainter p(this);
|
|||
|
|
p.setRenderHint(QPainter::Antialiasing, true);
|
|||
|
|
|
|||
|
|
// 绘制背景
|
|||
|
|
p.fillRect(rect(), QColor(245, 245, 245));
|
|||
|
|
|
|||
|
|
if (m_expanded) {
|
|||
|
|
// 展开模式:全屏显示图片,在左下角显示图片名称
|
|||
|
|
QRect imageRect = rect();
|
|||
|
|
|
|||
|
|
// 绘制图片区域
|
|||
|
|
if (!m_pix.isNull()) {
|
|||
|
|
// 计算保持比例的缩放,确保整个图片可见
|
|||
|
|
QPixmap scaled = m_pix.scaled(imageRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|||
|
|
|
|||
|
|
// 计算居中位置
|
|||
|
|
int x = imageRect.center().x() - scaled.width() / 2;
|
|||
|
|
int y = imageRect.center().y() - scaled.height() / 2;
|
|||
|
|
|
|||
|
|
// 绘制图片(完整显示,不超出区域)
|
|||
|
|
p.drawPixmap(x, y, scaled);
|
|||
|
|
} else {
|
|||
|
|
p.setPen(Qt::gray);
|
|||
|
|
p.drawText(imageRect, Qt::AlignCenter, "No Image");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} else {
|
|||
|
|
// 正常模式:图片完全显示,不拉伸
|
|||
|
|
QRect inner = rect().adjusted(8, 8, -8, -8);
|
|||
|
|
if (!m_pix.isNull()) {
|
|||
|
|
// 使用KeepAspectRatio保持比例,确保整个图片可见
|
|||
|
|
QPixmap scaled = m_pix.scaled(inner.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|||
|
|
|
|||
|
|
// 计算居中位置
|
|||
|
|
int x = inner.center().x() - scaled.width() / 2;
|
|||
|
|
int y = inner.center().y() - scaled.height() / 2;
|
|||
|
|
|
|||
|
|
p.drawPixmap(x, y, scaled);
|
|||
|
|
} else {
|
|||
|
|
p.setPen(Qt::gray);
|
|||
|
|
p.drawText(inner, Qt::AlignCenter, "No Image");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 在左下角显示图片名称
|
|||
|
|
if (!m_path.isEmpty()) {
|
|||
|
|
QFileInfo fileInfo(m_path);
|
|||
|
|
QString fileName = fileInfo.fileName();
|
|||
|
|
|
|||
|
|
p.setPen(Qt::black);
|
|||
|
|
QFont font = p.font();
|
|||
|
|
font.setPointSize(8);
|
|||
|
|
p.setFont(font);
|
|||
|
|
|
|||
|
|
QFontMetrics metrics(font);
|
|||
|
|
int textWidth = metrics.horizontalAdvance(fileName) + 10;
|
|||
|
|
int textHeight = metrics.height() + 4;
|
|||
|
|
|
|||
|
|
QRect textRect(5, height() - textHeight - 5, textWidth, textHeight);
|
|||
|
|
p.drawText(textRect, Qt::AlignCenter, fileName);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 绘制边框
|
|||
|
|
QPen border(m_selected ? QColor(66, 133, 244) : QColor(200, 200, 200));
|
|||
|
|
border.setWidth(m_selected ? 3 : 1);
|
|||
|
|
p.setPen(border);
|
|||
|
|
p.drawRoundedRect(rect().adjusted(1,1,-1,-1), 6, 6);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::mousePressEvent(QMouseEvent* ev) {
|
|||
|
|
if (ev->button() == Qt::LeftButton) emit clicked();
|
|||
|
|
QWidget::mousePressEvent(ev);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::resizeEvent(QResizeEvent* event) {
|
|||
|
|
QWidget::resizeEvent(event);
|
|||
|
|
updateShrinkButtonPosition();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ImageTileWidget::updateShrinkButtonPosition() {
|
|||
|
|
if (m_shrinkButton) {
|
|||
|
|
m_shrinkButton->move(width() - m_shrinkButton->width() - 5, 5);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QString ImageTileWidget::getImageInfo() const {
|
|||
|
|
if (m_path.isEmpty()) return "No image loaded";
|
|||
|
|
|
|||
|
|
QFileInfo fileInfo(m_path);
|
|||
|
|
QString info;
|
|||
|
|
|
|||
|
|
info += QString("文件名: %1\n").arg(fileInfo.fileName());
|
|||
|
|
info += QString("大小: %1 KB\n").arg(fileInfo.size() / 1024);
|
|||
|
|
info += QString("修改时间: %1\n").arg(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"));
|
|||
|
|
|
|||
|
|
if (!m_pix.isNull()) {
|
|||
|
|
info += QString("尺寸: %1 x %2\n").arg(m_pix.width()).arg(m_pix.height());
|
|||
|
|
info += QString("格式: %1\n").arg(QImageReader::imageFormat(m_path).constData());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return info;
|
|||
|
|
}
|