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

Qt Graphics View

       Graphics View框架是用来处理大量2D图形对象的,适合需要高效管理和交互的场景,比如绘图软件、地图编辑或者游戏。它和QPainter的区别在于,Graphics View提供了更高级别的对象管理,而QPainter更偏向于直接绘制。

一、核心组件

  1. QGraphicsScene(场景)

    • 作为图形项的容器,管理所有图元的存储、状态及事件传播‌。
    • 支持背景层、图形项层和前景层的分层绘制,可通过setBackgroundBrush()setForegroundBrush()设置背景/前景‌。
    • 提供碰撞检测、图元查询(如itemAt())及批量渲染(render())功能‌。
  2. QGraphicsView(视图)

    • 用于显示场景内容,支持多视图查看同一场景,提供缩放、旋转、平移等交互操作‌。
    • 可通过继承并重写mouseMoveEvent()mousePressEvent()等实现自定义交互逻辑(如坐标追踪、点击响应)‌。
  3. QGraphicsItem(图元)

    • 所有图形元素的基类,支持自定义形状、事件处理(如鼠标拖拽、键盘事件)及坐标变换‌14。
    • 典型应用包括可拖动的十字标记(CrossMarkItem)和可调整大小的兴趣区域(ROIRectItem)‌。

二、关键特性

  1. 事件处理

    • 图元可直接响应鼠标点击、悬停、拖拽及键盘事件,事件通过场景传播至目标图元‌。
      示例:
      通过重写hoverEnterEvent()hoverLeaveEvent()实现图元悬停缩放效果‌。
      重写 mousePressEvent()keyPressEvent() 等实现交互。
    • 使用 QGraphicsSceneContextMenuEvent 处理右键菜单。
  2. 性能优化

    • 通过设置QGraphicsItem::ItemIgnoresTransformations避免不必要的变换计算‌。
  3. 坐标转换‌:

    • 场景坐标 ↔ 视图坐标:QGraphicsView::mapToScene() 和 mapFromScene()
    • 项间坐标转换:QGraphicsItem::mapToItem() 和 mapFromItem()
  4. 动画与效果‌:

    • 动画‌: 使用 QPropertyAnimation 或 QGraphicsItemAnimation
    • 特效‌: 应用 QGraphicsEffect(如阴影、模糊)。
  5. 碰撞检测‌:

    • scene->collidingItems(item) 检测碰撞项。
    • QGraphicsItem::shape() 自定义碰撞形状。
  6. 性能优化‌:

    • 启用视图缓存:view.setCacheMode(QGraphicsView::CacheBackground)
    • 使用 QGraphicsItem::ItemIgnoresTransformations 避免项随视图缩放。

三、基本用法

// 创建场景和项
QGraphicsScene scene;
QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 50);

// 创建视图并关联场景
QGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing); // 抗锯齿
view.show();

 四、开发建议

  • 模块化设计‌:将图元、视图逻辑分离,便于维护扩展(如独立实现CrossMarkItemGraphView类)‌。
  • 交互优化‌:使用QGraphicsView::setDragMode()启用拖拽模式,提升用户体验‌。
  • 内存管理‌: 项通常由场景负责删除,手动删除需谨慎。
  • 渲染性能‌: 避免过多复杂项;考虑使用 OpenGL 加速(QGraphicsView::setViewport(new QOpenGLWidget))。
  • 调试工具‌:利用QGraphicsScene::selectedItems()和焦点管理功能辅助调试复杂交互逻辑‌。

五、实例代码

1、基础实例:场景与视图初始化

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

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    // 创建场景并设置范围
    QGraphicsScene *scene = new QGraphicsScene();
    scene->setSceneRect(0, 0, 800, 600);  // ‌:ml-citation{ref="1" data="citationList"}
    
    // 添加矩形图元
    QGraphicsRectItem *rectItem = new QGraphicsRectItem(100, 100, 200, 150);
    rectItem->setBrush(Qt::blue);
    scene->addItem(rectItem);  // ‌:ml-citation{ref="1,7" data="citationList"}
    
    // 创建视图并绑定场景
    QGraphicsView *view = new QGraphicsView(scene);
    view->setWindowTitle("Basic Example");
    view->show();
    
    return app.exec();
}

2、图元选择与坐标跟踪

实现功能‌:

  • 鼠标移动时实时显示场景坐标
  • 图元选中后支持键盘操作(删除、旋转、缩放)

关键代码‌:

// 继承 QGraphicsView 实现自定义视图
class CustomView : public QGraphicsView {
protected:
    void mouseMoveEvent(QMouseEvent *event) override {
        QPoint viewPos = event->pos();
        QPointF scenePos = mapToScene(viewPos);
        emit positionChanged(scenePos);  // 发送坐标信号
    }
};

// 图元选中后处理键盘事件
void MyItem::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_Delete:
            scene()->removeItem(this);  // 删除图元 ‌
            break;
        case Qt::Key_Space:
            setRotation(rotation() + 90);  // 旋转 90°
            break;
    }
}

3、自定义图元实例

实现功能‌:

  • 十字标记支持鼠标拖拽
  • 拖拽时实时更新位置信号

‌关键代码:

// CrossMarkItem.h
class CrossMarkItem : public QGraphicsItem {
public:
    QRectF boundingRect() const override {
        return QRectF(-size_/2, -size_/2, size_, size_);
    }
    
    void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) override {
        painter->drawLine(-size_/2, 0, size_/2, 0);  // 水平线
        painter->drawLine(0, -size_/2, 0, size_/2);   // 垂直线
    }
    
protected:
    QVariant itemChange(GraphicsItemChange change, const QVariant &value) override {
        if (change == ItemPositionChange) 
            emit positionChanged(value.toPointF());  // 发送位置变化信号
        return QGraphicsItem::itemChange(change, value);
    }
};

4、ROI 矩形与动态更新

实现功能‌:

  • 可调整大小的兴趣区域(ROI)
  • 实时显示 ROI 的坐标和尺寸

设计要点‌:

  • 继承 QGraphicsRectItem 并添加控制点
  • 在边缘点拖拽时更新 ROI 范围

‌关键代码: 

class ROIRectItem : public QGraphicsRectItem {
public:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {
        QPointF delta = event->pos() - event->lastPos();
        setRect(rect().adjusted(delta.x(), delta.y(), delta.x(), delta.y()));  // 动态调整矩形
    }
};

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

相关文章:

  • Qt 实操记录:打造自己的“ QQ 音乐播放器”
  • 马蜂窝携手腾讯云接入DeepSeek,率先应用于旅游AI智能应用“AI游贵州”
  • Ubuntu “文件系统根目录”上的磁盘空间不足
  • 【操作系统安全】任务4:Windows 系统网络安全实践里常用 DOS 命令
  • 河南大学移动应用开发实验报告1
  • Spring Boot Starter 启动器:简化依赖管理,快速构建应用
  • 自发自用省电费,余电上网稳收益!安科瑞分布式光伏监测系统智领绿色能源未来
  • 十七、实战开发 uni-app x 项目(仿京东)- 后端指南
  • 游戏服务器分区的分布式部署
  • Go基础语法阶段核心内容(5天)
  • 路由器安全研究:D-Link DIR-823G v1.02 B05 复现与利用思路
  • 使用 AJAX 前后端传递数据
  • 《Python实战进阶》No25: 自动化测试:unittest 与 pytest 的对比
  • Vue3项目中可以尝试封装那些组件
  • 删除 Git 历史提交记录中的大文件
  • 【css酷炫效果】实现鱼群游动动态效果
  • Docker和 Docker Compose安装MySQL:快速搭建数据库环境
  • 【STM32】从新建一个工程开始:STM32 新建工程的详细步骤
  • vue:组件的使用
  • Asp.net Core API 本地化