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

QT:QT场景视图

简介

在 Qt 中,场景视图框架(Scene - View Framework)提供了一个强大且灵活的方式来管理和显示 2D 图形元素。该框架主要由三个核心类组成:QGraphicsScene、QGraphicsView 和 QGraphicsItem,它们协同工作以实现复杂的 2D 图形界面。
在这里插入图片描述

核心类介绍

QGraphicsScene:场景类,作为一个容器,用于管理大量的 QGraphicsItem 对象。它不直接显示图形,而是负责存储和组织这些图形项,提供对图形项的添加、删除、查找等操作,同时处理图形项的碰撞检测、鼠标事件等。
QGraphicsView:视图类,它是一个可视化的窗口,用于显示 QGraphicsScene 中的内容。可以对视图进行缩放、平移、旋转等操作,还能处理用户的交互事件,如鼠标点击、滚动等。
QGraphicsItem:图形项类,是所有图形元素的基类。可以通过继承 QGraphicsItem 来创建自定义的图形项,如矩形、椭圆、文本等,每个图形项可以有自己的属性(如颜色、大小、位置等)和行为(如鼠标交互)。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建场景
    QGraphicsScene scene;

    // 创建矩形项
    QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 100, 50);
    rectItem->setBrush(Qt::red);
    // 将矩形项添加到场景中
    scene.addItem(rectItem);

    // 创建椭圆项
    QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem(150, 20, 80, 60);
    ellipseItem->setBrush(Qt::blue);
    // 将椭圆项添加到场景中
    scene.addItem(ellipseItem);

    // 创建视图
    QGraphicsView view(&scene);
    view.setWindowTitle("Qt Scene - View Example");
    view.resize(400, 300);
    view.show();

    return app.exec();
}

头文件包含:
QApplication:用于管理 Qt 应用程序的资源和事件循环。
QGraphicsScene:场景类,用于管理图形项。
QGraphicsView:视图类,用于显示场景内容。
QGraphicsRectItem 和 QGraphicsEllipseItem:分别用于创建矩形和椭圆图形项。
创建一个 QGraphicsScene 对象,作为图形项的容器。

创建一个红色的矩形项和一个蓝色的椭圆项,并使用 addItem 方法将它们添加到场景中。
创建一个 QGraphicsView 对象,将场景指针传递给它,设置窗口标题和大小,然后显示视图

在这里插入图片描述
看到一个窗口,其中显示了一个红色的矩形和一个蓝色的椭圆,这就是使用 Qt 场景视图框架创建的简单图形界面。

QGraphicsLineItem

用于绘制直线。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsLineItem>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QGraphicsLineItem *lineItem = new QGraphicsLineItem(20, 20, 200, 20);
    lineItem->setPen(QPen(Qt::blue, 2));
    scene.addItem(lineItem);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

QGraphicsPathItem

用于绘制任意形状的路径,可以通过 QPainterPath 来定义复杂的图形。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPathItem>
#include <QPainterPath>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QPainterPath path;
    path.moveTo(50, 50);
    path.lineTo(100, 100);
    path.lineTo(150, 50);
    QGraphicsPathItem *pathItem = new QGraphicsPathItem(path);
    pathItem->setBrush(Qt::yellow);
    pathItem->setPen(QPen(Qt::red, 2));
    scene.addItem(pathItem);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

QGraphicsPolygonItem

用于绘制多边形。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPolygonItem>
#include <QPolygonF>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QPolygonF polygon;
    polygon << QPointF(50, 50) << QPointF(100, 100) << QPointF(150, 50);
    QGraphicsPolygonItem *polygonItem = new QGraphicsPolygonItem(polygon);
    polygonItem->setBrush(Qt::green);
    polygonItem->setPen(QPen(Qt::black, 2));
    scene.addItem(polygonItem);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

QGraphicsTextItem

用于显示文本

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsTextItem>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QGraphicsTextItem *textItem = new QGraphicsTextItem("Hello, Qt!");
    textItem->setFont(QFont("Arial", 20));
    scene.addItem(textItem);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

QGraphicsItemGroup

用于将多个图形项组合成一个单一的图形项,方便对一组图形进行统一操作,如移动、旋转等。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>
#include <QGraphicsItemGroup>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;

    QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50);
    QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem(60, 0, 50, 50);

    QGraphicsItemGroup *group = new QGraphicsItemGroup;
    group->addToGroup(rectItem);
    group->addToGroup(ellipseItem);
    scene.addItem(group);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

自由拖动图形

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>

// 自定义可拖动矩形图形项类
class DraggableRectItem : public QGraphicsRectItem {
public:
    DraggableRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
        : QGraphicsRectItem(x, y, width, height, parent), isDragging(false) {
        // 开启图形项的鼠标交互属性
        setFlags(ItemIsMovable | ItemIsSelectable);
    }

protected:
    // 鼠标按下事件处理函数
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
        if (event->button() == Qt::LeftButton) {
            // 记录鼠标按下时的位置
            lastMousePos = event->scenePos();
            isDragging = true;
        }
        QGraphicsRectItem::mousePressEvent(event);
    }

    // 鼠标移动事件处理函数
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {
        if (isDragging) {
            // 计算鼠标在场景中的水平位移
            qreal dx = event->scenePos().x() - lastMousePos.x();
            // 只处理左右方向的拖动
            moveBy(dx, 0);
            // 更新上次鼠标位置
            lastMousePos = event->scenePos();
        }
        QGraphicsRectItem::mouseMoveEvent(event);
    }

    // 鼠标释放事件处理函数
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override {
        if (event->button() == Qt::LeftButton) {
            isDragging = false;
        }
        QGraphicsRectItem::mouseReleaseEvent(event);
    }

private:
    bool isDragging;
    QPointF lastMousePos;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建场景
    QGraphicsScene scene;

    // 创建可拖动的矩形图形项
    DraggableRectItem *rectItem = new DraggableRectItem(50, 50, 100, 50);
    rectItem->setBrush(Qt::blue);
    // 将矩形图形项添加到场景中
    scene.addItem(rectItem);

    // 创建视图
    QGraphicsView view(&scene);
    view.setWindowTitle("Draggable Rectangle");
    view.resize(400, 300);
    view.show();

    return app.exec();
}

在 DraggableRectItem 的构造函数中添加了 setFlags(ItemIsMovable | ItemIsSelectable);,这行代码开启了图形项的鼠标交互属性,使得图形项能够接收鼠标事件并进行相应的处理。这样修改后,矩形应该可以跟随鼠标左右拖动了。
在这里插入图片描述

QT 自定义图元实现鼠标左键:拖拽 鼠标滚动:拉伸 鼠标右键:旋转

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QMouseEvent>
#include <QWheelEvent>
// 添加 QGraphicsSceneMouseEvent 头文件
#include <QGraphicsSceneMouseEvent>

// 自定义图元类
class CustomGraphicsItem : public QGraphicsItem
{
public:
    CustomGraphicsItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent)
    {
        setFlags(ItemIsMovable | ItemIsSelectable);
        m_scale = 1.0;
        m_rotation = 0.0;
    }

    // 定义图元的边界矩形
    QRectF boundingRect() const override
    {
        return QRectF(-50, -50, 100, 100);
    }

    // 绘制图元
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(Qt::blue);
        painter->setBrush(Qt::lightGray);
        painter->scale(m_scale, m_scale);
        painter->rotate(m_rotation);
        painter->drawRect(-50, -50, 100, 100);
    }

protected:
    // 鼠标按下事件处理
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override
    {
        if (event->button() == Qt::LeftButton)
        {
            m_dragStartPos = event->pos();
        }
        QGraphicsItem::mousePressEvent(event);
    }

    // 鼠标移动事件处理
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
    {
        if (event->buttons() & Qt::LeftButton)
        {
            QPointF delta = event->pos() - m_dragStartPos;
            moveBy(delta.x(), delta.y());
        }
        QGraphicsItem::mouseMoveEvent(event);
    }

    // 鼠标滚轮事件处理
    void wheelEvent(QGraphicsSceneWheelEvent *event) override
    {
        if (event->delta() > 0)
        {
            m_scale *= 1.1;
        }
        else
        {
            m_scale /= 1.1;
        }
        update();
        QGraphicsItem::wheelEvent(event);
    }

    // 鼠标右键释放事件处理
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
    {
        if (event->button() == Qt::RightButton)
        {
            m_rotation += 15;
            update();
        }
        QGraphicsItem::mouseReleaseEvent(event);
    }

private:
    QPointF m_dragStartPos;
    qreal m_scale;
    qreal m_rotation;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建场景和视图
    QGraphicsScene scene;
    QGraphicsView view(&scene);

    // 创建自定义图元并添加到场景中
    CustomGraphicsItem *item = new CustomGraphicsItem;
    scene.addItem(item);

    // 显示视图
    view.show();

    return a.exec();
}

CustomGraphicsItem 类
构造函数:初始化图元的可移动和可选择属性,并设置初始的缩放比例和旋转角度。
boundingRect 函数:定义图元的边界矩形,用于确定图元的绘制范围。
paint 函数:使用 QPainter 绘制图元,应用当前的缩放和旋转变换。
mousePressEvent 函数:当鼠标左键按下时,记录鼠标的起始位置。
mouseMoveEvent 函数:当鼠标左键按住并移动时,根据鼠标的位移移动图元。
wheelEvent 函数:处理鼠标滚轮事件,根据滚轮的滚动方向进行缩放操作。
mouseReleaseEvent 函数:当鼠标右键释放时,将图元旋转 15 度。
2. main 函数
创建 QApplication 对象,用于管理应用程序的事件循环。
创建 QGraphicsScene 和 QGraphicsView 对象。
创建 CustomGraphicsItem 对象并添加到场景中。
显示视图并启动应用程序的事件循环。

在这里插入图片描述


http://www.kler.cn/a/564577.html

相关文章:

  • 材料分析方法和特点
  • JUC (java. util.concurrent) 的常见类及创建新线程的方法等 [Java EE 初阶]
  • 【缓存】缓存雪崩与缓存穿透:高并发系统的隐形杀手
  • MongoDB#Code和Function
  • Axure PR 9 中继器 03 翻页控制
  • 计算机网络之传输层(传输层的功能)
  • Ray Data 内部架构深度解析
  • C++ algorithm之shuffle函数
  • 光速解决phpstudy无法启动MySQL服务
  • Java—初始多线程
  • 【Java项目】基于Spring Boot的网上商城购物系统
  • 网络安全学习-常见安全漏洞检测以及修复方法-1
  • 泛微Ecode新增Button调用服务器中的JSP页面里的方法
  • Cannot resolve net.sf.json-lib:json-lib:2.4
  • 小红和小紫的拿球游戏(B组)
  • linux在vim中查找和替换
  • AI数据分析:用DeepSeek做数据清洗
  • ArcGIS Pro中打造精美高程渲染图的全面指南
  • 2025学年安徽省职业院校技能大赛 “信息安全管理与评估”赛项 比赛样题任务书
  • 数字IC后端设计实现OCC(On-chip Clock Controller)电路介绍及时钟树综合案例