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();
}
相关推荐
断眉的派大星几秒前
均值为0,方差为1:数据的“标准校服”
人工智能·机器学习·均值算法
小宋10212 分钟前
Java 项目结构 vs Python 项目结构:如何快速搭一个可跑项目
java·开发语言·python
A尘埃9 分钟前
电子厂PCB板焊点缺陷检测(卷积神经网络CNN)
人工智能·神经网络·cnn
Tadas-Gao10 分钟前
缸中之脑:大模型架构的智能幻象与演进困局
人工智能·深度学习·机器学习·架构·大模型·llm
中金快讯12 分钟前
新视野混合净值波动有几何?贝莱德基金回撤控制策略是否命中关键?
人工智能
楚兴15 分钟前
MacBook M1 安装 OpenClaw 完整指南
人工智能·后端
23遇见20 分钟前
探索CANN:开源AI计算底座的关键组件与技术思想
人工智能
jl486382126 分钟前
变比测试仪显示屏的“标杆“配置!如何兼顾30000小时寿命与六角矢量图精准显示?
人工智能·经验分享·嵌入式硬件·物联网·人机交互
2301_8187305636 分钟前
transformer(上)
人工智能·深度学习·transformer
一晌小贪欢38 分钟前
Python 爬虫进阶:如何利用反射机制破解常见反爬策略
开发语言·爬虫·python·python爬虫·数据爬虫·爬虫python