Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)
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命令代码如下:
|
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); glLoadIdentity(); painter->endNativePainting(); QRectF boundingRect () const private: |
绘制3D场景
QGraphicsScene类提供了三个层面:背景层、图元层和前景层。上面2D图形项的绘制都是在图元层,是一个2D场景,如果我们想要实现一个3D场景,则可以在背景或前景层使用OpenGL命令,而底层是3D场景,上面是2D场景的情况很类似于我们玩网络游戏的情景,所以常在背景层绘制3D场景。各层绘制顺序:背景层-图元层-前景层
|
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渲染)的更多相关文章
- 【Unity】13.1 场景视图中的GI可视化
分类:Unity.C#.VS2015 创建日期:2016-05-19 一.简介 在场景视图中设计不同的场景内容时,可以根据需要勾选相关的渲染选项,以便让场景仅显示其中的一部分或者全部渲染效果. 在这些 ...
- QT场景视图父子关系图元打印研究
在之前的一篇文章中,实现了QT场景视图的打印功能,主要通过render函数来实现,非常简单和方便. 在实际的项目需求中,除了打印整个场景外,还需要对单个图形进行打印操作,基于item的图形可以在pai ...
- 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题
之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...
- [Unity3D]开发视图中的标记 - Gizmos
这个类用来做自己的组件很不错,比如下面这个图的路径点,他其实是个Empty Object,可以自己加脚本让他带上标记.官方解释还可以用来做帮助提示的-.- 大游戏场景的制作时候,你可以用这个在地图上写 ...
- 如何在FineUIMvc(ASP.NET MVC)视图中绑定多个模型?
起因 这是知识星球内的一个网友提出的,按理说ASP.NET MVC中一个视图只能绑定一个模型(Model),在视图顶部标识如下: @model IEnumerable<FineUICore.Ex ...
- 【Unity】2.5 场景视图(Scene)
分类:Unity.C#.VS2015 创建日期:2016-03-29 一.场景视图(Scene View)导航 场景视图 (Scene View) 是你的交互式沙箱.你可以使用场景视图 (Scene ...
- PyQt(Python+Qt)学习随笔:视图中的dragDropMode属性对dragEnabled和acceptDrops属性的影响
老猿Python博文目录 老猿Python博客地址 在<PyQt(Python+Qt)学习随笔:QAbstractItemView的dragEnabled和dragDropMode属性的关系&g ...
- 使用VS2010开发Qt程序的4点经验(QT4到QT5的升级,更改sln文件,切换工程使用的Qt库,在VS的Solution Explorer视图中建立文件夹)
导读 相比于Qt Creator,我更喜欢用VS2010来进行开发.虽然启动时间相对较慢,但是VS下强大的快捷键和丰富的插件,以及使用多年的经验,都让我觉得在开发过程中得心应手.其中最重要的一点是,有 ...
- 第15.23节 PyQt(Python+Qt)入门学习:Model/View架构中QListView视图配套Model的开发使用
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView理论上可以和所有QAbstractItemModel派生的类如QStri ...
随机推荐
- Go语言调度器之创建main goroutine(13)
本文是<Go语言调度器源代码情景分析>系列的第13篇,也是第二章的第3小节. 上一节我们分析了调度器的初始化,这一节我们来看程序中的第一个goroutine是如何创建的. 创建main g ...
- 201871010121-王方-《面向对象程序设计(java)》第十二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...
- 201871010128-杨丽霞《面向对象程序设计(java)》第七周学习总
201871010128-杨丽霞-<面向对象程序设计(java)>第七周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- python结巴分词余弦相似度算法实现
过余弦相似度算法计算两个字符串之间的相关度,来对关键词进行归类.重写标题.文章伪原创等功能, 让你目瞪口呆.以下案例使用的母词文件均为txt文件,两种格式:一种内容是纯关键词的txt,每行一个关键词就 ...
- 使用angularJS接收json数据并进行数据的显示
1.引入JS <script type="text/javascript" src="../plugins/angularjs/angular.min.js&quo ...
- mysql的创建数据库表及添加数据
C:\Users\ceshi>mysql -u root -pEnter password: ******Welcome to the MySQL monitor. Commands end w ...
- Linux系统下root密码遗忘等系统故障的修复方法 - 运维总结
IDC机房有一台centos系统的服务器,由于这台服务器的系统装了好长时间,且root密码中间更新过几次,后面去机房现场维护时,登陆密码遗忘了,悲催啊~没办法,只能开机进入“单用户模式”进行密码重置了 ...
- 批处理教程之cls、pause命令
cls 命令 清除屏幕.执行该命令后,屏幕上的所有信息都被清除,光标重新定位至屏幕左上角. REM 和 :: REM为注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显. 其次 ...
- appium--Toast元素识别
前戏 Android中的Toast是一种简易的消息提示框,当视图显示给用户,在应用程序中显示为浮动,和Dialog不一样的是,它永远不会获得焦点,无法被点击 Toast类的思想就是尽可能不引人注意,同 ...
- 开源推荐 - CoDo开源一站式DevOps平台
一群有梦想的年轻人开源了一个云管理平台,他们的口号是:让天下没有996的运维 有幸参与到CoDo项目的开发,这是一个非常棒的一站式开源运维平台,分享给大家 平台介绍 CODO是一款为用户提供企业多混合 ...