Qt Demo(3) 之 deepseek 帮我写的关于图像显示的小界面

Qt Demo(3) 之 deepseek 帮我写的关于图像显示的小界面

  • 一个完整的图像浏览器实现,支持缩放、拖拽和坐标显示功能。
  • 实现提供了一个功能完整、界面美观的图像浏览器,展示了 QGraphicsView、QGraphicsScene 和 QGraphicsPixmapItem 的核心功能和使用方法。
  • 界面如下图所示:

界面功能介绍

  • 关键实现细节

具体实现代码

  • imageviewer.h
cpp 复制代码
#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QPointF>

class ImageViewer : public QGraphicsView
{
    Q_OBJECT

public:
    explicit ImageViewer(QWidget* parent = nullptr);

    // 图像操作
    bool loadImage(const QString& fileName);
    void setImage(QImage& qimage);
    void clearImage();

    // 视图操作
    void zoomIn();
    void zoomOut();
    void resetView();
    void fitToWindow();

    // 获取当前状态
    bool hasImage() const;
    double scaleFactor() const;

signals:
    // 坐标变化信号
    void mousePositionChanged(const QPointF& scenePos);

protected:
    // 事件处理
    void wheelEvent(QWheelEvent* event) override;
    void mousePressEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;

private:
    // 初始化设置
    void setupView();

    // 缩放控制
    void scaleView(double factor);

    // 成员变量
    QGraphicsScene* scene;
    QGraphicsPixmapItem* pixmapItem;
    double currentScale;
    bool isDragging;
    QPoint lastDragPos;
};

#endif // IMAGEVIEWER_H
  • imageviewer.cpp
cpp 复制代码
#include "imageviewer.h"
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QFileDialog>
#include <QMessageBox>
#include <QScrollBar>
#include <QtMath>

ImageViewer::ImageViewer(QWidget* parent)
    : QGraphicsView(parent), scene(nullptr), pixmapItem(nullptr),
    currentScale(1.0), isDragging(false)
{
    // 创建场景
    scene = new QGraphicsScene(this);
    setScene(scene);

    // 设置视图属性
    setupView();
}

void ImageViewer::setupView()
{
    // 设置渲染提示
    setRenderHint(QPainter::Antialiasing, true);
    setRenderHint(QPainter::SmoothPixmapTransform, true);
    setRenderHint(QPainter::TextAntialiasing, true);

    // 设置视图属性
    setDragMode(QGraphicsView::ScrollHandDrag);
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setResizeAnchor(QGraphicsView::AnchorUnderMouse);
    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setFrameShape(QFrame::NoFrame);

    // 设置背景
    setBackgroundBrush(QBrush(QColor(50, 50, 50)));
}

bool ImageViewer::loadImage(const QString& fileName)
{
    // 加载图像
    QPixmap pixmap(fileName);
    if (pixmap.isNull()) {
        return false;
    }

    // 清除现有内容
    clearImage();

    // 创建新的图像项
    pixmapItem = scene->addPixmap(pixmap);
    scene->setSceneRect(pixmap.rect());

    // 重置视图
    resetView();

    return true;
}

void ImageViewer::setImage(QImage& qimage)
{
    // 清除现有内容
    clearImage();

    QPixmap pixmap = QPixmap::fromImage(qimage);

    // 创建新的图像项
    pixmapItem = scene->addPixmap(pixmap);
    scene->setSceneRect(pixmap.rect());

    // 重置视图
    resetView();
}

void ImageViewer::clearImage()
{
    // 清除场景
    scene->clear();
    pixmapItem = nullptr;
    currentScale = 1.0;
}

void ImageViewer::zoomIn()
{
    scaleView(1.2);
}

void ImageViewer::zoomOut()
{
    scaleView(1.0 / 1.2);
}

void ImageViewer::resetView()
{
    // 重置变换
    //resetTransform();
    fitToWindow();
    currentScale = 1.0;

    // 如果存在图像,居中显示
    if (pixmapItem) {
        centerOn(pixmapItem);
    }
}

void ImageViewer::fitToWindow()
{
    if (pixmapItem) {
        // 适应窗口大小
        fitInView(scene->sceneRect(), Qt::KeepAspectRatio);

        // 更新当前缩放比例
        QTransform transform = this->transform();
        currentScale = transform.m11();
    }
}

bool ImageViewer::hasImage() const
{
    return pixmapItem != nullptr;
}

double ImageViewer::scaleFactor() const
{
    return currentScale;
}

void ImageViewer::scaleView(double factor)
{
    // 应用缩放
    scale(factor, factor);
    currentScale *= factor;
}

void ImageViewer::wheelEvent(QWheelEvent* event)
{
    if (pixmapItem) {
        // 计算缩放因子
        double factor = qPow(1.2, event->angleDelta().y() / 240.0);
        scaleView(factor);
        event->accept();
    }
    else {
        QGraphicsView::wheelEvent(event);
    }
}

void ImageViewer::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton && pixmapItem) {
        // 开始拖拽
        setCursor(Qt::ClosedHandCursor);
        lastDragPos = event->pos();
        isDragging = true;
        event->accept();
    }
    else {
        QGraphicsView::mousePressEvent(event);
    }
}

void ImageViewer::mouseMoveEvent(QMouseEvent* event)
{
    if (pixmapItem) {
        // 获取场景坐标
        QPointF scenePos = mapToScene(event->pos());

        // 发射坐标变化信号
        emit mousePositionChanged(scenePos);

        // 处理拖拽
        if (isDragging && (event->buttons() & Qt::LeftButton)) {
            // 计算移动距离
            QPoint delta = event->pos() - lastDragPos;
            lastDragPos = event->pos();

            // 移动滚动条
            horizontalScrollBar()->setValue(horizontalScrollBar()->value() - delta.x());
            verticalScrollBar()->setValue(verticalScrollBar()->value() - delta.y());

            event->accept();
        }
        else {
            QGraphicsView::mouseMoveEvent(event);
        }
    }
    else {
        QGraphicsView::mouseMoveEvent(event);
    }
}

void ImageViewer::mouseReleaseEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton && isDragging) {
        // 结束拖拽
        setCursor(Qt::ArrowCursor);
        isDragging = false;
        event->accept();
    }
    else {
        QGraphicsView::mouseReleaseEvent(event);
    }
}
  • mainwindow.h
cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStatusBar>
#include <QLabel>
#include "imageviewer.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

private slots:
    void openImage();
    void updateStatusBar(const QPointF& scenePos);

private:
    void setupUI();
    void setupConnections();

    ImageViewer* imageViewer;  //图像显示
    QStatusBar* statusBar;    //状态栏
    QLabel* coordLabel;     //显示坐标
    QLabel* scaleLabel;     //显示缩放尺度

    // 工具栏动作
    QAction* openAction;      //打开图像
    QAction* zoomInAction;    //缩小
    QAction* zoomOutAction;   //放大
    QAction* resetViewAction; //恢复视野
    QAction* fitToWindowAction;   //适应窗口大小
};

#endif // MAINWINDOW_H
  • mainwindow.cpp
cpp 复制代码
#include "mainwindow.h"
#include <QToolBar>
#include <QFileDialog>
#include <QMessageBox>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
{
    setupUI();
    setupConnections();
    setWindowTitle("Image Browser");
    resize(1000, 700);
}

MainWindow::~MainWindow()
{
}

void MainWindow::setupUI()
{
    // 创建图像查看器
    imageViewer = new ImageViewer(this);
    setCentralWidget(imageViewer);

    // 创建状态栏
    statusBar = new QStatusBar();
    setStatusBar(statusBar);

    coordLabel = new QLabel("Coordinates: (0, 0)");
    scaleLabel = new QLabel("Scale: 100%");
    statusBar->addPermanentWidget(coordLabel);
    statusBar->addPermanentWidget(scaleLabel);

    // 创建工具栏
    QToolBar* toolBar = new QToolBar("Main Toolbar");
    addToolBar(Qt::TopToolBarArea, toolBar);

    // 创建动作
    openAction = new QAction("Open", this);
    zoomInAction = new QAction("Zoom In", this);
    zoomOutAction = new QAction("Zoom Out", this);
    resetViewAction = new QAction("Reset View", this);
    fitToWindowAction = new QAction("Fit to Window", this);

    // 添加到工具栏
    toolBar->addAction(openAction);
    toolBar->addAction(zoomInAction);
    toolBar->addAction(zoomOutAction);
    toolBar->addAction(resetViewAction);
    toolBar->addAction(fitToWindowAction);

    // 设置样式
    setStyleSheet(R"(
        QMainWindow {
            background-color: #2b2b2b;
        }
        QToolBar {
            background-color: #3c3c3c;
            color: #ffffff;
            border: none;
            spacing: 3px;
            padding: 3px;
        }
        QToolButton {
            background-color: #4c4c4c;
            color: #ffffff;
            border: 1px solid #5c5c5c;
            border-radius: 3px;
            padding: 5px;
        }
        QToolButton:hover {
            background-color: #5c5c5c;
        }
        QStatusBar {
            background-color: #3c3c3c;
            color: #ffffff;
        }
        QLabel {
            color: #ffffff;
        }
    )");
}

void MainWindow::setupConnections()
{
    connect(openAction, &QAction::triggered, this, &MainWindow::openImage);
    connect(zoomInAction, &QAction::triggered, imageViewer, &ImageViewer::zoomIn);
    connect(zoomOutAction, &QAction::triggered, imageViewer, &ImageViewer::zoomOut);
    connect(resetViewAction, &QAction::triggered, imageViewer, &ImageViewer::resetView);
    connect(fitToWindowAction, &QAction::triggered, imageViewer, &ImageViewer::fitToWindow);
    connect(imageViewer, &ImageViewer::mousePositionChanged, this, &MainWindow::updateStatusBar);
}

void MainWindow::openImage()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        "Open Image", "", "Image Files (*.png *.jpg *.jpeg *.bmp *.tif)");

    if (!fileName.isEmpty())
    {
        // 加载图像
        QImage qimage(fileName);
        if (qimage.isNull()) 
        {
            QMessageBox::warning(this, "Error", "Cannot load image file.");
        }
        else {
            imageViewer->setImage(qimage);
        }

       /* if (!imageViewer->loadImage(fileName)) {
            QMessageBox::warning(this, "Error", "Cannot load image file.");
        }*/
    }
}

void MainWindow::updateStatusBar(const QPointF& scenePos)
{
    // 更新坐标显示
    coordLabel->setText(QString("Coordinates: (%1, %2)").arg(scenePos.x()).arg(scenePos.y()));

    // 更新缩放比例显示
    int scalePercent = static_cast<int>(imageViewer->scaleFactor() * 100);
    scaleLabel->setText(QString("Scale: %1%").arg(scalePercent));
}
  • main.cpp
cpp 复制代码
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
相关推荐
银二码13 小时前
flutter踩坑插件:Swift架构不兼容
开发语言·flutter·swift
一蓑烟雨,一任平生13 小时前
h5实现内嵌微信小程序&支付宝 --截图保存海报分享功能
开发语言·前端·javascript
Ares-Wang14 小时前
JavaScript》》JS》》ES6》》 数组 自定义属性
开发语言·javascript·es6
七夜zippoe14 小时前
Java 技术支撑 AI 系统落地:从模型部署到安全合规的企业级解决方案(一)
java·人工智能·安全
一碗白开水一14 小时前
【论文阅读】Sparse4D v3:Advancing End-to-End 3D Detection and Tracking
论文阅读·人工智能·目标检测·3d·自动驾驶
要做朋鱼燕14 小时前
【C++】 Vector容器操作全解析
开发语言·c++·笔记·学习笔记
信息快讯14 小时前
光学神经网络与人工智能应用
人工智能·深度学习·神经网络
MiaoChuAI14 小时前
新手也能轻松选!秒出PPT和豆包AI PPT优缺点解析
人工智能·powerpoint
利刃大大14 小时前
【高并发内存池】三、线程缓存的设计
开发语言·c++·缓存·项目·内存池