#include "DialogImageViewer.h" #include #include #include #include #include #include #include DialogImageViewer::DialogImageViewer(QWidget* parent) : QDialog(parent) { setupUI(); } DialogImageViewer::~DialogImageViewer() { } void DialogImageViewer::setupUI() { // 设置窗口属性 setWindowTitle(QString::fromUtf8("图像查看")); setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); setStyleSheet("background-color: rgb(25, 26, 28);"); // 获取屏幕大小,设置窗口为屏幕的80% QScreen* screen = QApplication::primaryScreen(); QRect screenGeometry = screen->availableGeometry(); int width = screenGeometry.width() * 0.8; int height = screenGeometry.height() * 0.8; resize(width, height); // 主布局 QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(10); // 滚动区域 m_scrollArea = new QScrollArea(this); m_scrollArea->setWidgetResizable(false); m_scrollArea->setAlignment(Qt::AlignCenter); m_scrollArea->setStyleSheet( "QScrollArea { background-color: rgb(38, 40, 47); border: none; }" "QScrollBar:vertical { background-color: rgb(38, 40, 47); width: 12px; }" "QScrollBar::handle:vertical { background-color: rgb(80, 82, 88); border-radius: 6px; min-height: 20px; }" "QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0px; }" "QScrollBar:horizontal { background-color: rgb(38, 40, 47); height: 12px; }" "QScrollBar::handle:horizontal { background-color: rgb(80, 82, 88); border-radius: 6px; min-width: 20px; }" "QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal { width: 0px; }" ); // 图像标签 m_imageLabel = new QLabel(m_scrollArea); m_imageLabel->setAlignment(Qt::AlignCenter); m_imageLabel->setStyleSheet("background-color: rgb(38, 40, 47);"); m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); m_imageLabel->setScaledContents(false); m_scrollArea->setWidget(m_imageLabel); mainLayout->addWidget(m_scrollArea, 1); // 底部信息栏 QHBoxLayout* bottomLayout = new QHBoxLayout(); bottomLayout->setSpacing(20); m_infoLabel = new QLabel(this); m_infoLabel->setStyleSheet("QLabel { color: rgb(180, 180, 180); font-size: 14px; }"); m_infoLabel->setText(QString::fromUtf8("滚轮缩放 | 拖拽平移 | 双击还原 | ESC退出")); bottomLayout->addWidget(m_infoLabel); bottomLayout->addStretch(); // 关闭按钮 QPushButton* btnClose = new QPushButton(QString::fromUtf8("关闭"), this); btnClose->setFixedSize(100, 35); btnClose->setStyleSheet( "QPushButton { background-color: rgb(60, 62, 68); color: rgb(221, 225, 233); " "border: 1px solid rgb(80, 82, 88); border-radius: 5px; font-size: 14px; }" "QPushButton:hover { background-color: rgb(80, 82, 88); }" "QPushButton:pressed { background-color: rgb(50, 52, 58); }" ); connect(btnClose, &QPushButton::clicked, this, &QDialog::close); bottomLayout->addWidget(btnClose); mainLayout->addLayout(bottomLayout); // 设置焦点策略以接收键盘事件 setFocusPolicy(Qt::StrongFocus); } void DialogImageViewer::setImage(const QImage& image, const QString& title) { m_originalImage = image; m_scaleFactor = 1.0; if (!title.isEmpty()) { setWindowTitle(QString::fromUtf8("图像查看 - %1").arg(title)); } // 计算初始缩放比例,使图像适应窗口 if (!m_originalImage.isNull()) { QSize viewSize = m_scrollArea->viewport()->size(); double scaleX = static_cast(viewSize.width() - 20) / m_originalImage.width(); double scaleY = static_cast(viewSize.height() - 20) / m_originalImage.height(); m_scaleFactor = qMin(scaleX, scaleY); m_scaleFactor = qMax(m_scaleFactor, MIN_SCALE); m_scaleFactor = qMin(m_scaleFactor, 1.0); // 初始不放大超过100% } updateImageDisplay(); } void DialogImageViewer::updateImageDisplay() { if (m_originalImage.isNull()) { m_imageLabel->setText(QString::fromUtf8("无图像")); return; } // 计算缩放后的尺寸 int newWidth = static_cast(m_originalImage.width() * m_scaleFactor); int newHeight = static_cast(m_originalImage.height() * m_scaleFactor); // 缩放图像 QImage scaledImage = m_originalImage.scaled(newWidth, newHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); m_imageLabel->resize(scaledImage.size()); // 更新信息标签 QString info = QString::fromUtf8("缩放: %1% | 尺寸: %2x%3 | 滚轮缩放 | 拖拽平移 | 双击还原") .arg(static_cast(m_scaleFactor * 100)) .arg(m_originalImage.width()) .arg(m_originalImage.height()); m_infoLabel->setText(info); } void DialogImageViewer::resetZoom() { if (m_originalImage.isNull()) return; // 重置为适应窗口的缩放比例 QSize viewSize = m_scrollArea->viewport()->size(); double scaleX = static_cast(viewSize.width() - 20) / m_originalImage.width(); double scaleY = static_cast(viewSize.height() - 20) / m_originalImage.height(); m_scaleFactor = qMin(scaleX, scaleY); m_scaleFactor = qMax(m_scaleFactor, MIN_SCALE); updateImageDisplay(); // 居中显示 m_scrollArea->horizontalScrollBar()->setValue( (m_imageLabel->width() - m_scrollArea->viewport()->width()) / 2); m_scrollArea->verticalScrollBar()->setValue( (m_imageLabel->height() - m_scrollArea->viewport()->height()) / 2); } void DialogImageViewer::wheelEvent(QWheelEvent* event) { if (m_originalImage.isNull()) return; // 获取滚轮方向 double delta = event->angleDelta().y() > 0 ? SCALE_STEP : -SCALE_STEP; // 计算新的缩放比例 double newScale = m_scaleFactor + delta; newScale = qMax(newScale, MIN_SCALE); newScale = qMin(newScale, MAX_SCALE); if (qAbs(newScale - m_scaleFactor) > 0.001) { // 保存当前滚动位置比例 QScrollBar* hBar = m_scrollArea->horizontalScrollBar(); QScrollBar* vBar = m_scrollArea->verticalScrollBar(); double hRatio = hBar->maximum() > 0 ? static_cast(hBar->value()) / hBar->maximum() : 0.5; double vRatio = vBar->maximum() > 0 ? static_cast(vBar->value()) / vBar->maximum() : 0.5; m_scaleFactor = newScale; updateImageDisplay(); // 恢复滚动位置比例 hBar->setValue(static_cast(hRatio * hBar->maximum())); vBar->setValue(static_cast(vRatio * vBar->maximum())); } event->accept(); } void DialogImageViewer::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { m_dragging = true; m_lastPos = event->pos(); setCursor(Qt::ClosedHandCursor); } QDialog::mousePressEvent(event); } void DialogImageViewer::mouseMoveEvent(QMouseEvent* event) { if (m_dragging) { QPoint delta = event->pos() - m_lastPos; m_lastPos = event->pos(); QScrollBar* hBar = m_scrollArea->horizontalScrollBar(); QScrollBar* vBar = m_scrollArea->verticalScrollBar(); hBar->setValue(hBar->value() - delta.x()); vBar->setValue(vBar->value() - delta.y()); } QDialog::mouseMoveEvent(event); } void DialogImageViewer::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { m_dragging = false; setCursor(Qt::ArrowCursor); } QDialog::mouseReleaseEvent(event); } void DialogImageViewer::mouseDoubleClickEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { resetZoom(); } QDialog::mouseDoubleClickEvent(event); } void DialogImageViewer::keyPressEvent(QKeyEvent* event) { switch (event->key()) { case Qt::Key_Escape: close(); break; case Qt::Key_Plus: case Qt::Key_Equal: // 放大 m_scaleFactor = qMin(m_scaleFactor + SCALE_STEP, MAX_SCALE); updateImageDisplay(); break; case Qt::Key_Minus: // 缩小 m_scaleFactor = qMax(m_scaleFactor - SCALE_STEP, MIN_SCALE); updateImageDisplay(); break; case Qt::Key_0: // 原始大小 m_scaleFactor = 1.0; updateImageDisplay(); break; case Qt::Key_F: // 适应窗口 resetZoom(); break; default: QDialog::keyPressEvent(event); } }