当前位置: 首页 > news >正文

qt使用笔记三之 QGraphicsView、QGraphicsScene 和 QGraphicsPixmapItem 详解

qt使用笔记三之 QGraphicsView、QGraphicsScene 和 QGraphicsPixmapItem 详解

  • Qt的Graphics View框架提供了一个强大的平台,用于管理和交互大量的自定义2D图形项。这三个核心类构成了该框架的基础:

    • QGraphicsScene:作为图形项的容器,管理所有图形项

    • QGraphicsView:作为可视化窗口,用于显示场景内容

    • QGraphicsPixmapItem:用于显示图像的专用图形项

1. QGraphicsScene(图形场景)

  • QGraphicsScene 是 Qt Graphics View 框架中的场景类,它充当所有图形项的容器。场景定义了项目的坐标空间,并负责管理大量图形项的状态,如选择、焦点和悬停等。
主要特性:- 管理大量图形项的高效容器- 传播事件到各个图形项- 提供无变换的场景坐标系统- 管理图形项的选择、聚焦和悬停状态- 提供场景渲染的基类
  • 常用方法:
// 添加和移除图形项
QGraphicsItem* addItem(QGraphicsItem *item);
void removeItem(QGraphicsItem *item);// 查找图形项
QList<QGraphicsItem*> items() const;
QList<QGraphicsItem*> items(Qt::SortOrder order = Qt::DescendingOrder) const;// 场景边界管理
void setSceneRect(const QRectF &rect);
QRectF sceneRect() const;// 渲染
void render(QPainter *painter, const QRectF &target = QRectF(), const QRectF &source = QRectF(), Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);// 事件处理
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

2. QGraphicsView(图形视图)

  • QGraphicsView 是用于可视化 QGraphicsScene 内容的窗口部件。它提供了滚动条、变换(缩放和旋转)以及将场景渲染到不同绘图设备的能力。
主要特性:提供滚动条以便浏览大场景支持变换(缩放和旋转)可以将场景渲染到不同的绘图设备支持多种渲染后端(OpenGL、普通绘图等)提供多种交互模式
  • 常用方法:
// 场景管理
void setScene(QGraphicsScene *scene);
QGraphicsScene* scene() const;// 视图变换
void scale(qreal sx, qreal sy);
void rotate(qreal angle);
void translate(qreal dx, qreal dy);
void resetTransform();// 视图模式设置
void setDragMode(DragMode mode); // ScrollHandDrag, RubberBandDrag等// 坐标转换
QPointF mapToScene(const QPoint &point) const;
QPoint mapFromScene(const QPointF &point) const;// 渲染控制
void setRenderHint(QPainter::RenderHint hint, bool on = true);
void setViewportUpdateMode(ViewportUpdateMode mode);

3. QGraphicsPixmapItem(位图图形项)

  • QGraphicsPixmapItem 是 QGraphicsItem 的子类,专门用于显示 QPixmap 图像。它提供了图像显示、变换和交互的基本功能。
主要特性:在图形场景中专用于显示QPixmap图像实现透明度 和 图像的变换(缩放、旋转等)作为复杂图形场景的背景或元素可以设置偏移量和变换原点
  • 常用方法:
// 图像管理
void setPixmap(const QPixmap &pixmap);
QPixmap pixmap() const;// 偏移量设置
void setOffset(const QPointF &offset);
void setOffset(qreal x, qreal y);
QPointF offset() const;// 变换模式
void setTransformationMode(Qt::TransformationMode mode);
Qt::TransformationMode transformationMode() const;// 图形项属性
virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr);

三者的关系

QGraphicsView (视图/窗口)|| 显示|
QGraphicsScene (场景/容器)|| 包含|
QGraphicsPixmapItem (图形项/图像)
  • 一个场景可以有多个视图
  • 一个场景可以包含多个图形项
  • 视图负责将场景内容呈现给用户

4. 封装好的 图像显示类

  • imageviewer.h
#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QPointF>class ImageViewer : public QGraphicsView
{Q_OBJECTpublic: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
#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);}
}
http://www.xdnf.cn/news/1433161.html

相关文章:

  • 大模型常用的数据类型FP32,BF16,FP16
  • 基于arm芯片的驱动开发——温湿度传感器dht11
  • Java 垃圾回收机制(GC算法、GC收集器如G1、CMS)的必会知识点汇总
  • Java面试实战系列【JVM篇】- JVM内存结构与运行时数据区详解(共享区域)
  • JavaSE丨异常处理详解,高效应对程序中的“意外”
  • 结构抗震与土木工程研究
  • Windows控制台颜色修改
  • 移动端网页设计vm+rem,和px实现方式对比
  • 【设计模式】三大原则 单一职责原则、开放-封闭原则、依赖倒转原则
  • Javascript》》JS》》ES6》 Map、Set、WeakSet、WeakMap
  • 【MATLAB绘图进阶】(3.1)从基础到高级的图形样式控制
  • Android14 init.rc各个阶段的主要操作详解2
  • gbase8s之导出mysql导入gbase8s
  • 良策金宝AI:电力工程的“最强大脑”,如何重塑设计新范式?
  • css中的v-bind 动态变化
  • 技术架构设计--资源与链接、安全灾备
  • Android URC 消息透传 MTK 代码方案
  • T40N君正/INGENIC专业嵌入式CPU计算能力,集成XBurst2双核处理器(1.2GHz)、RISC-V协处理器和神经网络加速器(2TOPS算力)
  • 防止应用调试分析IP被扫描加固实战教程
  • 宋红康 JVM 笔记 Day11|直接内存
  • 爬虫基础学习 - Beautifulsoup
  • 电子电子技术知识------MOSFET管
  • 高校党建信息管理系统的设计与实现-(源码+LW+可部署)
  • 实验4-HTTP协议的运行过程
  • 【大前端】Vue 和 React 主要区别
  • React 中 key 的作用
  • C#---共享项目
  • 解决戴尔笔记本电脑键盘按键部分失灵
  • python 创建websocket教程
  • 从自动化到智能化:家具厂智能化产线需求与解决方案解析