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

Qt/C++面试【速通笔记九】—视图框架机制

在Qt中,QGraphicsViewQGraphicsScene是用于构建二维图形界面的核心组件。它们的设计使得开发者能够高效地管理和渲染图形项,支持丰富的用户交互,例如缩放、旋转、平移等。


1. QGraphicsScene和QGraphicsView的基本概念

QGraphicsScene

QGraphicsScene 是Qt中的图形场景类,它负责管理所有的图形项(即QGraphicsItem)。场景本身定义了一个坐标系统(场景坐标),用于描述所有图形项的位置、大小、状态等。可以理解为图形项的容器,所有图形项都可以添加到场景中。

QGraphicsView

QGraphicsView 是一个视图窗口,它通过渲染QGraphicsScene中的图形项将场景的内容显示到屏幕上。它提供了缩放、旋转、平移等功能,能够让用户与图形项进行交互。QGraphicsView将场景坐标转换为视图坐标,从而影响图形项在屏幕上的显示位置。


2. QGraphicsView框架的主要组件

  • QGraphicsScene:用于管理和存储图形项(如矩形、线条、图片等)。
  • QGraphicsItem:图形项,是场景中的具体内容,可以是任何可视化元素,如矩形、圆形、图片等。
  • QGraphicsView:用于显示QGraphicsScene,并为用户提供交互功能。

3. 坐标系统与坐标转换

QGraphicsView框架中,有三个常见的坐标系统:

  1. 场景坐标(Scene Coordinates):这是场景中的全局坐标系统,所有图形项的位置和大小都通过场景坐标来定义。
  2. 视图坐标(View Coordinates):这是视图窗口的局部坐标系统,表示图形项在屏幕上的显示位置。由于视图支持缩放、平移等操作,视图坐标会随着这些变换而变化。
  3. 项坐标(Item Coordinates):这是图形项内部的局部坐标系统,描述图形项内部元素的位置。例如,矩形项的左上角坐标。
坐标转换

Qt提供了几种方法来进行坐标系统之间的转换。通过这些转换,您可以方便地在不同坐标系统之间进行转换,确保图形项、场景和视图的协调。

从场景坐标到视图坐标

假设您有一个场景坐标scenePoint,可以使用QGraphicsView::mapFromScene()方法将其转换为视图坐标:

QPointF scenePoint(50, 50);  // 场景中的点
QPointF viewPoint = view.mapFromScene(scenePoint);  // 转换为视图坐标
从视图坐标到场景坐标

如果您有一个视图坐标viewPoint,可以使用QGraphicsView::mapToScene()方法将其转换为场景坐标:

QPointF viewPoint(200, 150);  // 视图中的点
QPointF scenePoint = view.mapToScene(viewPoint);  // 转换为场景坐标
从项坐标到场景坐标

对于图形项,假设您有一个局部坐标localPoint,可以使用QGraphicsItem::mapToScene()方法将其转换为场景坐标:

QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 100, 100);
QPointF localPoint(20, 20);  // 项坐标
QPointF scenePoint = rectItem->mapToScene(localPoint);  // 转换为场景坐标
从场景坐标到项坐标

如果您有场景坐标scenePoint,并且希望知道它相对于某个图形项的位置,可以使用QGraphicsItem::mapFromScene()方法:

QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 100, 100);
QPointF scenePoint(50, 50);  // 场景坐标
QPointF localPoint = rectItem->mapFromScene(scenePoint);  // 转换为项坐标

4. QGraphicsView的交互功能

QGraphicsView不仅用于显示场景,还提供了多种交互功能,例如缩放、平移、旋转等。这些功能可以大大增强用户体验,让应用程序更具交互性。

视图缩放

通过鼠标滚轮事件或者键盘快捷键,您可以实现视图的缩放。例如,可以使用scale()方法来缩放视图:

view.scale(1.2, 1.2);  // 放大视图
view.scale(0.8, 0.8);  // 缩小视图
视图平移

可以使用translate()方法平移视图的内容:

view.translate(50, 50);  // 将视图内容平移50个像素
视图旋转

QGraphicsView还支持视图的旋转操作:

view.rotate(45);  // 旋转视图45度

5. 完整示例:QGraphicsView的使用

下面是一个完整的Qt示例,展示了如何创建一个QGraphicsSceneQGraphicsView,并实现一些基本功能,如坐标转换、鼠标点击事件、缩放等:

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QMouseEvent>
#include <QDebug>class MyView : public QGraphicsView {
public:MyView(QGraphicsScene *scene) : QGraphicsView(scene) {setRenderHint(QPainter::Antialiasing);setRenderHint(QPainter::SmoothPixmapTransform);}protected:void mousePressEvent(QMouseEvent *event) override {QPointF viewPoint = event->pos();  // 获取视图坐标QPointF scenePoint = mapToScene(viewPoint);  // 转换为场景坐标qDebug() << "Mouse clicked at view point:" << viewPoint << ", scene point:" << scenePoint;}void wheelEvent(QWheelEvent *event) override {if (event->angleDelta().y() > 0) {scale(1.2, 1.2);  // 放大} else {scale(0.8, 0.8);  // 缩小}}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);QGraphicsScene scene;QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 100, 100);rectItem->setBrush(Qt::blue);  // 设置矩形颜色为蓝色scene.addItem(rectItem);MyView view(&scene);  // 使用自定义视图类view.show();return app.exec();
}

6. QGraphicsView常用函数一览

在使用QGraphicsView时,您将会用到一些常见的函数。下面是一些QGraphicsView类的主要函数及其功能:

分组函数功能描述
场景void setScene()设置关联显示的场景
void setSceneRect()设置场景在视图中可见的部分的矩形区域
void setAlignment()设置场景在视图中的对齐方式,缺省是上左对齐
外观void setBackgroundBrush()设置场景的背景画刷
void setForegroundBrush()设置场景的前景画刷
void setRenderHints()设置视图的绘制选项
交互void setInteractive()是否允许场景可交互,如果禁用交互,则任何键盘盘或鼠标操作都被忽略
QRect rubberBandRect()返回选择矩形框区域
void setRubberBandSelectionMode()选择模式,参数为枚举类型Qt::ItemSelectionMode
坐标QPoint mapFromScene()将场景中的点转换为视图中的坐标
QPointF mapToScene()将视图中的点转换为场景中的坐标

http://www.xdnf.cn/news/413137.html

相关文章:

  • EHS 安全管理有效落地,五步实施方法解析
  • 基于SpringBoot的博客系统测试报告
  • slackel系统详解
  • MACH-ETH:汽车网络接口的卓越之选
  • steam OS详细讲解
  • yolov5s.pt这类的后续是pt的文件用什么软件可以打开看
  • STM32F103_LL库+寄存器学习笔记12.1 - 串口DMA高效收发实战:引入ringbuffer结构
  • STM32实现循环队列
  • 系统架构-通信系统架构设计
  • 如何理解“数组也是对象“——Java中的数组
  • old kali网站下载链接爬取-Kali linux 全部版本镜像下载--Index of /kali-images
  • 基于STM32、HAL库的DPS368XTSA1气压传感器 驱动程序设计
  • [Windows] Honeyview V5.53
  • 深度解析Crawl4AI:面向大模型的新一代智能爬虫
  • 2025系统架构师考试押题总结
  • 学习黑客Windows 任务管理器详解
  • 解决WSL、Ubuntu的.ico图标不正确显示缩略图
  • VBA会被Python代替吗
  • LeetCode:513、找树左下角的值
  • 滑动窗口/单调队列
  • [网络层]ICMP协议
  • Java——API基础(String类和StringBuilder类)
  • 手写 vue 源码 === computed 实现
  • JavaScript高级进阶(七)
  • shell命令大全
  • 基于STM32、HAL库的BMP581气压传感器 驱动程序设计
  • springBoot中的Starter-启动器
  • 重学安卓14/15自由窗口freeform企业实战bug-学员作业
  • 本地文件查重管理工具EasyFileCount v3.0.5.1绿色版,支持查找大重复文件+自动分类
  • 客户端限流主要采用手段:纯前端验证码、禁用按钮、调用限制和假排队