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()将视图中的点转换为场景中的坐标

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客晨风

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值