QT自带例程Boxes使用QT Graphics View框架实现了2D图形和3D图形的混合渲染,综合性比较强,整合知识较多,值得学习。

  • 可以使用鼠标通过以下方式控制演示中的元素:
  • 按住鼠标左键的同时拖动鼠标可以旋转中心的Box。
  • 按住鼠标右键的同时拖动鼠标会旋转卫星箱。
  • 按住鼠标滚轮的同时拖动鼠标会旋转整个3D背景层。
  • 滚动鼠标滚轮可放大和缩小场景。

选项窗格可用于微调Demo中的各种参数,包括颜色和像素着色器

原始的在Widget中绘图通过重写paintEvent绘图响应函数,在其中使用QPainter来绘制。

存在问题:

1、 支持更多的图形时函数体会很长

2、 移动操作图形时会很费劲

Graphics View基本架构

Graphics View设计为管理大量2D图形,每一个2D图形都是一个item,其类为QGraphicsItem,QT内置了椭圆、矩形、直线、路径、图像、多边形和文本等基本item,可以通过派生QGraphicsItem来实现自定义的item,需要重写boundingRect以及paint函数。

QGraphicsScene场景类包含所有的items,并且充当了一个view与items之间的接口桥梁。其拥有所有的图形item,可以传播绘制事件以及其他鼠标事件,而且提供了定位和管理图形item的各种方便的方法。

场景初始化:

QGraphicsScene *scene = new QGraphicsScene(this);

scene->setSceneRect(-100, -100, 201, 201);

场景中添加图形item:

QGraphicsItem *item = scene->addRect(20, 20, 60, 60,

QPen(Qt::red, 3),

QBrush(Qt::green));

QGraphicsView视图类widget充当了显示一个场景(场景是虚拟的)的视口。

QGraphicsView *view = new QGraphicsView();

QGraphicsScene *scene = setupScene();

view->setScene(scene);

为了能在场景中添加QT基本的图形组件(如PushButton、LineEdit等),QT提供了QGraphicsWidget类,为了进一步能使得图形item使用信号-槽的功能,QT又提供了QGraphicsObject类,非常的全面周到。

QGraphicsProxyWidget *button = scene->addWidget(new QPushButton(tr("Click me!")));

button->setPos(20, -30);

图形项item交互操作

图形项item的flags控制着它们如何可以与之互动

  • ItemIsMovable     -  一个方便的功能,原始鼠标事件方法让用户拖动
  • ItemIsSelectable   - 使用setSelected和QGraphicsScene :: setSelectionArea方法选择
  • ItemIsFocusable   - 获取键盘焦点

场景通过BSP树管理图形项item,二进制空间分区树存储图形项于一棵树中,主要取决于它们在空间的位置。

绘制各种2D图形项

OpenGL渲染

为了使用OpenGL渲染场景,需要更改view的视口widget:

QGraphicsView *view = new QGraphicsView();

view->setViewport(new QGLWidget);

绘制3D图形项

一般地,图形项的绘制时在paint函数中使用QPainter来绘制,QPainer是绘制2D图形的类,而想绘制3D图形则需要使用OpenGL API,同样滴,在paint中是OpenGL命令代码如下:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
class MyItem : public QGraphicsItem
{
public:
    MyItem( QGraphicsItem *parent = ) {}
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
               QWidget *widget)
    {
        painter->drawRect(boundingRect());
        painter->beginNativePainting();
        /* Reset The Current Viewport And Perspective Transformation */

glViewport(, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(.0f);
        glMatrixMode(GL_MODELVIEW);

glLoadIdentity();
        glTranslatef(.0f);
        glBegin(GL_TRIANGLES);
        glVertex3f(.0f);
        glVertex3f(-.0f);
        glVertex3f(.0f);
        glEnd();

painter->endNativePainting();
    }

QRectF boundingRect () const
    {
        , w, h);
    }

private:
    int w, h;
};

绘制3D场景

QGraphicsScene类提供了三个层面:背景层、图元层和前景层。上面2D图形项的绘制都是在图元层,是一个2D场景,如果我们想要实现一个3D场景,则可以在背景或前景层使用OpenGL命令,而底层是3D场景,上面是2D场景的情况很类似于我们玩网络游戏的情景,所以常在背景层绘制3D场景。各层绘制顺序:背景层-图元层-前景层

 C++ Code 
1
2
3
4
5
6
 
void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->beginNativePainting();
    // do opengl draw…
    painter->endNativePainting();
}

Box例程学习:

在Windows上安装的QT版本在build该例程时会出现错误,提示缺少opengl-desktop版本的支持,这是由于windows的发布版本QT没有使用该选项(只能重新编译QT源代码了),而linux版本使用了该选项可以正常构建运行。

Qt Graphics View + OpenGL Render:

QGLWidget *widget = new QGLWidget(QGLFormat(QGL::SampleBuffers));

widget->makeCurrent();

Scene scene(1024, 768, maxTextureSize);

GraphicsView view;

view.setViewport(widget);

view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

view.setScene(&scene);

view.show();

类图:

Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)的更多相关文章

  1. 【Unity】13.1 场景视图中的GI可视化

    分类:Unity.C#.VS2015 创建日期:2016-05-19 一.简介 在场景视图中设计不同的场景内容时,可以根据需要勾选相关的渲染选项,以便让场景仅显示其中的一部分或者全部渲染效果. 在这些 ...

  2. QT场景视图父子关系图元打印研究

    在之前的一篇文章中,实现了QT场景视图的打印功能,主要通过render函数来实现,非常简单和方便. 在实际的项目需求中,除了打印整个场景外,还需要对单个图形进行打印操作,基于item的图形可以在pai ...

  3. 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题

    之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...

  4. [Unity3D]开发视图中的标记 - Gizmos

    这个类用来做自己的组件很不错,比如下面这个图的路径点,他其实是个Empty Object,可以自己加脚本让他带上标记.官方解释还可以用来做帮助提示的-.- 大游戏场景的制作时候,你可以用这个在地图上写 ...

  5. 如何在FineUIMvc(ASP.NET MVC)视图中绑定多个模型?

    起因 这是知识星球内的一个网友提出的,按理说ASP.NET MVC中一个视图只能绑定一个模型(Model),在视图顶部标识如下: @model IEnumerable<FineUICore.Ex ...

  6. 【Unity】2.5 场景视图(Scene)

    分类:Unity.C#.VS2015 创建日期:2016-03-29 一.场景视图(Scene View)导航 场景视图 (Scene View) 是你的交互式沙箱.你可以使用场景视图 (Scene ...

  7. PyQt(Python+Qt)学习随笔:视图中的dragDropMode属性对dragEnabled和acceptDrops属性的影响

    老猿Python博文目录 老猿Python博客地址 在<PyQt(Python+Qt)学习随笔:QAbstractItemView的dragEnabled和dragDropMode属性的关系&g ...

  8. 使用VS2010开发Qt程序的4点经验(QT4到QT5的升级,更改sln文件,切换工程使用的Qt库,在VS的Solution Explorer视图中建立文件夹)

    导读 相比于Qt Creator,我更喜欢用VS2010来进行开发.虽然启动时间相对较慢,但是VS下强大的快捷键和丰富的插件,以及使用多年的经验,都让我觉得在开发过程中得心应手.其中最重要的一点是,有 ...

  9. 第15.23节 PyQt(Python+Qt)入门学习:Model/View架构中QListView视图配套Model的开发使用

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView理论上可以和所有QAbstractItemModel派生的类如QStri ...

随机推荐

  1. No archetypes currently available. The archetype list will refresh when the indexes finish updating

    配置方法: 1. 在卡住的而画面点击"config" 2. 点击"Add remote catalog", 然后设置华为云的maven仓库地址, 然后点击&qu ...

  2. elipse常用插件下载

    https://www.douban.com/note/142165105/ https://marketplace.eclipse.org/ http://maven.aliyun.com/nexu ...

  3. 【oracle】迁表结构和数据

    背景:把一些表和数据从某库迁到另一个库 1.命令框: exp yktsh/yktsh_2019@orcl30 file=d:\yktsh20191201.dmp log=d:\daochu; exp ...

  4. Spring Cloud微服务安全实战_4-3_订单微服务&价格微服务

    实现一个场景: 订单微服务: POM: <?xml version="1.0" encoding="UTF-8"?> <project xml ...

  5. 学习vue_01

    目录 vue 框架: 框架介绍 基础格式 插值表达式: 文本指令: 事件指令: 属性指令: 小结: js 补充(面向对象): vue 框架: --构建虚拟的DOM结构,(内存内改变对象)- 操作数据的 ...

  6. Vue插槽详解 | 什么是插槽?

    作者 | Jeskson 来源 | 达达前端小酒馆 什么是插槽?插槽的指令为v-slot,它目前取代了slot和slot-scope,插槽内容,vue实例一套内容分发的api,将slot元素作为承载分 ...

  7. 一次失败的尝试:arm(aarch64架构)上使用docker运行Gogs

    环境 Ubuntu aarch64(好像是arm8的一种) Docker安装指南:https://docs.docker.com/install/linux/docker-ce/ubuntu/ Gog ...

  8. 关于DTO的定义问题。以及C#语言扩展的思考。

    数据传输对象 是我们经常用到的一个东西.有时候我们称之为的ViewModel也属于其中之一. 但是以往,我们总是 复制 实体类型的一些字段 然后单独创建这些对象.然后我们使用对象映射工具 进行值层面的 ...

  9. mysql数据库备份工具xtrabackup

    1.下载二进制安装包 其他高版本测试缺少依赖 2.xtrabackup参数说明 简介:  Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工 ...

  10. c#中怎样取得某坐标点的颜色

    // x,y 分别为x轴,y轴坐标 返回System.Drawing.Color 可以直接显示 public System.Drawing.Color GetPixelColor(int x, int ...