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

发布于:2025-05-15 ⋅ 阅读:(12) ⋅ 点赞:(0)

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


网站公告

今日签到

点亮在社区的每一天
去签到