-
2022-03-26 13:23:05
文章目录
1、介绍
图形项框架,主要由三部分组成,场景、图形项、视图,图形项是放在场景上,场景是看不到的, 需要用视图来显示他。
下载 https://gitee.com/xiaozhu0809/qt-graphic-view-frame/tree/master/
// 使用
#include <QApplication> #include <QGraphicsScene> #include "myitem.h" #include "myview.h" #include <QGraphicsView> #include <QDebug> #include <QPixmap> int main(int argc,char* argv[]) { QApplication app(argc,argv); QGraphicsScene scene; MyItem* item = new MyItem; scene.addItem(item); MyView* myview = new MyView; myview->setScene(&scene); myview->show(); return app.exec(); }
更多相关内容 -
QT 视图框架总结
2022-02-17 15:56:49视图框架里面的一些体会Qt 图形视图框架<二>——<QGraphicsView、QGraphicsScene> - 灼光 - 博客园
1 如果在widget里面添加 一个 ui->graphicsView窗口,这里面设置graphicsView的pos,是以widget的原点(左上角(0,0))为坐标,添加一个sence,这里是sence的坐标是以自己的中心为原点,不是窗口的(0,0),这里设置ui->graphicsView的宽和高的一半为sence的坐上的pos的x和y
MyView::MyView()
{
resize(400, 400); 视图大小
setBackgroundBrush(QPixmap("../graphicsview03/back.jpg"));
QGraphicsScene *scene = new QGraphicsScene(this); sence的父亲为view
scene->setSceneRect(0, 0, 200, 200);//相对于view的坐标
QGraphicsRectItem *item1 = new QGraphicsRectItem(0,0,20,20);
item1->setBrush(Qt::red);
item1->setPos(10,0);//相对于sence坐标
//scene->addItem(item1);
QGraphicsRectItem *item2 = new QGraphicsRectItem(0,0,20,20);
item2->setBrush(Qt::green);
item2->setPos(40,0);
//scene->addItem(item2);
//新建图形项组
QGraphicsItemGroup *group = new QGraphicsItemGroup;
group->addToGroup(item1);
group->addToGroup(item2);
scene->addItem(group);
setScene(scene);
setAlignment(Qt::AlignLeft | Qt::AlignTop);
//手型拖动
setDragMode(QGraphicsView::ScrollHandDrag);
scene->setSceneRect(0, 0, 800, 800);
QGLWidget *widget =new QGLWidget(this);
setViewport(widget);
//输出(10, 0)点的图形项
qDebug() << "itemAt(10,0) : " <<itemAt(10, 0);
qDebug() << "itemAt(40,0) : " <<itemAt(40, 0);
qDebug() << "#################################";
}
2
boundingRect()这个函数,是说明item的区域范围。在那个范围里面有效,是以scence原点为基础
2 item 设置在窗口里面的位置的时候,也是以view的坐标为pos的x和y,item自己的中心为原点和view不一样
pixItem->setPos(ui->graphicsView->x(),ui->graphicsView->y());//中心位置 我们这里是按照widget的坐标原点设置pos
QGraphicsScene scene(0, 0, 200, 200);//场景,设置的是基于屏幕原点的坐标
for(int i=0;i<2;i++)
{
MyItem* item = new MyItem;
item->setColor(QColor(qrand()%256,qrand()%256,qrand()%256));
//item->setColor(QColor(200,200,200+10*i));
item->setPos(0,50*i+2);//这个点是这个item的中心点
//item->setRect(QRectF(i*50,50,5,5));
scene.addItem(item);
qDebug()<<"123454"<<item->boundingRect().width()<<item->boundingRect().height();
}
QGraphicsView view;
view.setScene(&scene);
view.setSceneRect(0,0,200,200);//设置显示窗口大小
view.show();
3 item 添加
setFlag(QGraphicsItem::ItemIsFocusable); setFlag(QGraphicsItem::ItemIsMovable);
可以实现item拖动
4 以鼠标点为中心的放大和缩小添加下面两句
//以鼠标为中心进行缩放
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);//当转换时候view应该如何摆放场景的位置
setResizeAnchor(QGraphicsView::AnchorUnderMouse);5 滚动滑轮,view 放大和缩小了,并且按照鼠标点击点放大。
void MyGraphicsView::wheelEvent ( QWheelEvent * event )
{
// 获取当前鼠标相对于view的位置;
QPointF cursorPoint = event->pos();
// 获取当前鼠标相对于scene的位置;
QPointF scenePos = this->mapToScene(QPoint(cursorPoint.x(), cursorPoint.y()));
// 获取view的宽高;
qreal viewWidth = this->viewport()->width();
qreal viewHeight = this->viewport()->height();
// 获取当前鼠标位置相当于view大小的横纵比例;
qreal hScale = cursorPoint.x() / viewWidth;
qreal vScale = cursorPoint.y() / viewHeight;
// 当前放缩倍数;
qreal scaleFactor = this->matrix().m11();
int wheelDeltaValue = event->delta();
// 向上滚动,放大,只是全部的放大和缩小;
if (wheelDeltaValue > 0)
{
this->scale(1.2, 1.2);
}
// 向下滚动,缩小;
else
{
this->scale(1.0 / 1.2, 1.0 / 1.2);
}
QPointF viewPoint = this->matrix().map(scenePos);
// 通过滚动条控制view放大缩小后的展示scene的位置;
horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale));
verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));
}
-
Qt图形视图框架详解
2021-06-09 03:51:00介绍Qt中的Graphics View Framework,涉及View、Scene、Item的关系,如何自定义QGraphicsItem、处理Item之间的关联、如何布局及定义自己的布局Item、如何变幻Item、如何应用动画、如何处理拖放、如何给Item应用图形... -
QT图形视图框架
2021-04-15 10:05:56(1) 在Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。 (2) Graphics View支持事件传播体系结构,可以使图元场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标...文章目录
Graphics View框架结构的主要特点
Graphics View框架结构的主要特点如下:
(1) 在Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。
(2) Graphics View支持事件传播体系结构,可以使图元场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标事件。其中,鼠标事件包括鼠标被按下、移动、释放和双击,还可以跟踪鼠标的移动。
(3) 在Graphics View框架中,通过二元空间划分树(Binary Space Partitioning,BSP)提供快速的图元查找,这样就能够实时地显示包含上百万个图元的大场景。
Graphics View框架结构的三元素
Graphics View框架结构主要包含了场景类(QGraphicsScene)、视图类(QGraphicsView)和图元类(QGraphicsItem)。场景类提供了一个用于管理位于其中的众多图元容器,视图类用于显示场景中的图元,一个场景可以通过多个视图表现,一个场景包括多个几何图形。它们三者之间的关系可用图表示:
1、场景类:QGraphicsScene类
它是一个用于放置图元的容器,本身是不可见的,必须通过与之相连的视图类来显示及与外界进行交互操作。
场景类主要完成的工作包括提供对它包含的图元的操作接口和传递事件、管理各个图元的状态(如选择和焦点处理)、提供无变换的绘制功能(如打印)等。
事件传播体系结构将场景事件发送给图元,同时也管理图元之间的事件传播。如果场景接收了在某一点的鼠标单击事件,场景会将事件传给这一点的图元。
函数 功能描述 QGraphicsScene::addItem( ) 可以添加一个图元到场景中 QGraphicsScene::items( ) 和一些重载函数能够返回和点、矩形、多边形或向量路径相交的所有图元。 QGraphicsScene::itemAt( ) 返回指定点的最顶层图元。 QGraphicsScene::setSelectedAreas() 选择图元,选择区域可以是任意的形状,使用QPainterpath表示。 QGraphicsScene::selectedItems( ) 得到当前选择的图元列表。 QGraphicsScene::setFocusItem( )
或QGraphicsScene::setFocus( )设置图元的焦点。 QGraphicsScene::focusItem( ) 函数获得当前具有焦点的图元。 QGraphicsScene::reader( ) 函数在绘图设备上绘制场景。
2、视图类: QGraphicsView 类
它提供一个可视的窗口,用于显示场景中的图元。在同一个场景中可以有多个视图,也可以为相同的数据集提供几种不同的视图。视图接收键盘和鼠标的输入事件,并将它们翻译为场景事件(将坐标转换为场景的坐标)。
函数 功能描述 QGraphicsView::setViewport( ) 将视图设置为QGLWidget。 QGraphicsView::matrix( ) 可以变换场景的坐标,实现场景缩放和旋转。 QGraphicsView::mapToScene( )
和QGraphicsView::mapFromScene( )用于场景的坐标进行转换。
3、图元类(QGraphicsItem)
它是场景中各个图元的基类,在它的基础上可以继承出各种图元类,Qt已经预置的包括直线(QGraphicsLineItem)、椭圆(QGraphicsEllipseItem)、文本图元(QGraphicsTextItem)、矩形(QGraphicsRectItem)等。当然,也可以在QGraphicsItem类的基础上实现自定义的图元类,即用户可以继承QGraphicsItem实现符合自己需要的图元。
QGraphicsItem主要支持如下功能:
- 鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件。
- 处理键盘输入事件。
- 拖 处理拖曳事件。
- 碰撞检测。
此外,图元有自己的坐标系统,也提供场景和图元。图元还可以通过QGraphicsItem::matrix( )函数来进行自身的交换,可以包含子图元。
Graphics Viewk框架结构的坐标系统
Graphics View 坐标基于笛卡儿坐标系,一个图元的场景具有x坐标和y坐标。当使用没有变换的视图观察场景时,场景中的一个单元对应屏幕上的一个像素。
三个Graphics View 基本类有各自不同的坐标系,场景坐标、视图坐标和图元坐标。Graphics View提供了三个坐标系统之间的转换函数。在绘制图形时,GraphicsView 的场景坐标对应QPainter的逻辑坐标、视图坐标和设备坐标。
1.场景坐标
场景坐标是所有图元的基础坐标系统。场景坐标系统描述了项层的图元,每个图元都有场景坐标和相应的包容框。场景坐标的原点在场景中心,坐标原点是x轴正方向向右,y轴正方向向下。
QGraphicsScene类的坐标系以中心为原点(0,0), 如下图所示。
2.视图坐标
视图坐标是窗口部件的坐标。视图坐标的单位是像素。QGraphicsView视口的左上角是(0,0),X轴正方向向右,Y轴正方向向下。所有的鼠标事件最开始都是使用视图坐标。
QGraphicsView类继承自QWidget类,因此它和其他的QWidget类一样以窗口的左上角作为自己坐标系的原点,如下图所示。
3、图元坐标
图元使用自己的本地坐标,这个坐标系统通常以图元中心为原点,这也是所有变换的原点。图元坐标方向是X轴正方向向右,Y轴正方向向下。创建图元后,只需要注意图元坐标就可以了,QGraphicsScene和QGraphicsView会完成所有的变换。
QGraphicsItem类的坐标系,在调用QGraphicsItem类的paint()函数重画图元时则以此坐标系为基准,如下图所示。
根据需要,Qt提供了这三个坐标系之间的互相转换函数,以及图元与图元之间的转换函数,若需从QGraphicstem坐标系中的某点坐标转换到场景中的坐标,则可调用QGraphicstem 的mapToScene( )函数进行映射。而GraphicsItem的mapToParent()函数则可将QGraphicsItem 坐标
系中的某点坐标映射至它的上一级坐标系中,有可能是场景坐标,也有可能是另一个QGraphicsItem坐标。Graphics View框架提供了多种变换函数,如下表所示:
映射函数 转换类型 QGraphicsView::mapToScene() 视图到场景 QGraphicsView::mapFromScene() 场景到视图 QGraphicsItem:: mapFromScene() 场景到图元 QGraphicsItem:: mapToScene() 图元到场景 QGraphicsItem:: mapToParent() 子图元到父图元 QGraphicsItem:: mapFromParent() 父图元到子图元 QGraphicsItem:: mapToItem() 本图元到其他图元 QGraphicsItem:: mapFromItem() 其他图元到本图元 图形视图实例
设计界面,一只蝴蝶在屏幕上不停地上下飞舞。
操作步骤:
(1) 新建Qt Widgets Application(这里是Qt5,Qt4选Qt GUI应用),项目名为“Buterly", 基类选择”QMainWindow"(这个随便吧,后面用不到),类名命名默认为“MainWindow",取消“创建界面”复选框的选中状态。单击“下一步”按钮,最后单击“完成”按钮,完成该项目工程的建立。
(2)在“Butterfly" 项目名上单击鼠标右键,在弹出的快捷菜单中选择“添加新文件…”选
项,在弹出的对话框中选择“C++类”选项。单击“Choose…”按钮,在弹出的对话框的“Base
class"下拉列表框中选择基类名“QObject",在“类名"文本框中输入类的名称“Butterfly".
(3) 单击“下一步”按钮,单击“完成”按钮,添加文件“buttrfly.h" 和"butterfly.cpp”。
(4) Butterly 类继承自QObject类、QGraphicstem 类(这个自己添加),在头文件Butterfly.h"中完成的代码如下:butterfly.h
文件:#ifndef BUTTERFLY_H #define BUTTERFLY_H #include <QObject> #include <QGraphicsItem> #include <QPainter> #include <QGraphicsScene> #include <QGraphicsView> class Butterfly : public QObject,public QGraphicsItem { Q_OBJECT public: explicit Butterfly(QObject *parent = 0); void timerEvent(QTimerEvent *); QRectF boundingRect() const; protected: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: bool up; QPixmap pix_up; QPixmap pix_down; qreal angle; //qreal是float的类型定义 }; #endif // BUTTERFLY_H
其中,
(a)void timerEvent(QTimerEvent*)
:定时器实现动画的原理是在定时器的 timerEvent() 中对QGraphicsItem进行重绘。
(b)QRectF boundingRect() const
:为图元限定区域范围,所有继承自QGraphicsItem的自定义图元都必须实现此函数。
©bool up
:用于标志蝴蝶翅膀的位置(位于上或下),以便实现动态效果。butterfly.cpp
文件#include "butterfly.h" #include <math.h> const static double PI = 3.1416; Butterfly::Butterfly(QObject *parent) : QObject(parent) { up = true; //给蝴蝶位置的变量赋初值 pix_up.load("./image/up.jpg"); //调用Qpixmap的load()函数加载所用到的图片 pix_down.load("./image/down.jpg"); //图片地址看图片写 startTimer(100); //启动定时器,并设置时间间隔为100毫秒 }
boundingRect( ) 函数为图元限定区域范围。此范围是以图元自身的坐标系为基础设定的。具体实现代码如下:
QRectF Butterfly::boundingRect() const { qreal adjust = 10; return QRectF(-pix_up.width()/2-adjust,-pix_up.height()/2-adjust,\ pix_up.width()+adjust*2,pix_up.height()+adjust*2); }
在重画函数paint() 中,首先判断当前已显示的图片是pix_up还是pix_down。实现蝴蝶翅膀上下飞舞效果时,若当前显示的是pix_up图片,则重绘pix_down图片,反之亦然。具体实现代码如下:
void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { if(up) { painter->drawPixmap(boundingRect().topLeft(),pix_up); up=!up; } else { painter->drawPixmap(boundingRect().topLeft(),pix_down); up=!up; } }
定时器的timerEvent() 函数实现蝴蝶的飞舞,具体实现代码如下:
void Butterfly::timerEvent(QTimerEvent *) { qreal edgex = scene()->sceneRect().right()+boundingRect().width()/2; //限定蝴蝶飞舞的右边界 qreal edgetop = scene()->sceneRect().top()+boundingRect().height()/2; //限定蝴蝶飞舞的上边界 qreal edgebottom = scene()->sceneRect().bottom()+boundingRect().height()/2; //限定蝴蝶飞舞的下边界 if(pos().x()>=edgex) //若超过了右边界,则水平移回左边界处 setPos(scene()->sceneRect().left(),pos().y()); if(pos().y()<=edgetop) //若超过了上边界,则垂直移回下边界处 setPos(pos().x(),scene()->sceneRect().bottom()); if(pos().y()>=edgebottom) //若超过了下边界,则垂直移回上边界处 setPos(pos().x(),scene()->sceneRect().top()); angle+=(qrand()%10)/20.0; qreal dx = fabs(sin(angle*PI)*10.0); qreal dy = (qrand()%20)-10.0; setPos(mapToParent(dx,dy)); }
其中,
(a) setPos(mapToParent(dx,dy)):dx、dy完成蝴蝶随机飞行的路径,且dx、dy是相对于蝴蝶的坐标系而言的,因此应使用mapToParent() 函数映射为场景的坐标。main.cpp
文件#include <QtGui/QApplication> //注意:Qt5没有QtGui的,我这里是用Qt4建立的 #include <QGraphicsScene> #include "butterfly.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QGraphicsScene *scene = new QGraphicsScene; scene->setSceneRect(QRectF(-200,-200,400,400)); Butterfly *butterfly = new Butterfly; butterfly->setPos(-100,0); scene->addItem(butterfly); QGraphicsView *view = new QGraphicsView; view->setScene(scene); view->resize(400,400); view->show(); return a.exec(); }
图片:
运行效果:
-
Qt开发技术:图形视图框架(一)基本介绍
2021-04-17 11:03:41图形视图框架(The Graphic View Framework)用于管理和与大量定制的二维图形项目交互,以及用于可视化项目的视图小部件,支持缩放和旋转。若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/115791408长期持续带来更多项目与技术分享,咨询请加QQ:21497936、微信:yangsir198808
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
Qt开发专栏:开发技术(点击传送门)
上一篇:无
下一篇:《Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解》
前话
使用到Qt的视图框架。
Qt视图框架介绍
简介
图形视图框架(The Graphic View Framework)用于管理和与大量定制的二维图形项目交互,以及用于可视化项目的视图小部件,支持缩放和旋转。
该框架包括一个事件传播体系结构,允许对场景中的项目进行精确的双精度交互。项目可以处理按键事件、鼠标按下、移动、释放和双击事件,还可以跟踪鼠标移动。
图形视图使用BSP(Binary Space Partitioning,即二进制空间分区)树提供非常快读得项目发现,因此,它可以实时现实大型场景,即使有数百万个项目。
图形视图提供了一种基于项目得模型视图变成方法,多个视图可以观察单个场景,并且场景包含不同几何图形的项目。场景(The Scene)
QGraphicsScene提供了图形视图场景,场景有如下职责:
- 为管理大量项目(图元项目)提供快速界面;(实测同一个区域不能重叠多了,绘制会卡顿)
- 将事件传播到每个项;
- 管理项目状态,如选择和焦点处理;
- 提供未转换的渲染功能;主要用于打印;
该场景用作QGraphicsItem对象的容器。通过调用QGraphicsItem::additem() 将项添加到场景中,然后通过调用多个项发现函数之一来检索项。QGraphicsItem::items()及其重载返回由点、矩形、多边形或常规矢量路径包含或与之相交的所有项。QGraphicsItem::itemAt()返回特定点的最上面的项。所有项目发现功能都按降序堆叠顺序返回项目(即第一个返回的项目是最上面的,最后一个项目是最下面的)。
QGraphicsScene scene; QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100)) QTransform transform;; QGraphicsItem *item = scene.itemAt(50, 50, transform); // item == rect
QGraphicsScene的事件传播体系结构安排将场景事件传递到项目,并管理项目之间的传播。如果场景在某个位置接收到鼠标按下事件,则场景将事件传递到该位置的任何项目。
QGraphicsScene还管理某些项状态,例如项选择和焦点。可以通过调用QGraphicsScene::setSelectionArea(),传递任意形状来选择场景中的项目。该功函数还可用作QGraphicsView中橡皮擦的选择区域。要获取所有当前选定项的列表,请调用QGraphicscene::selecteditems()。QGraphicsScene处理的另一个状态是项是否具有键盘输入焦点。可以通过调用QGraphicScene::setFocusItem()或 QGraphicsItem::setFocus()对项设置焦点,也可以通过调用QGraphicscene::focusItem()获取当前焦点项。
最后,QGraphicScene允许您通过QGraphicScene::render()函数将部分场景渲染到绘制设备中。可以“打印”部分了解更多有关此内容的信息。视图(The View)
QGraphicsView提供了视图小部件,它可以可视化场景的内容。可以将多个视图附加到同一场景中,以便在同一数据集中提供多个视口。视图小部件是一个滚动区域,并提供滚动条用于在大型场景中导航。要启用OpenGL支持,可以通过调用QGraphicsView::setViewport()将QGLWidget设置为视区。
QGraphicsScene scene; myPopulateScene(&scene); QGraphicsView view(&scene); view.show();
在将事件发送到可视化场景之前,视图从键盘和鼠标接收输入事件,并将其转换为场景事件(在适当的情况下将使用的坐标转换为场景坐标)。
用转换矩阵QGraphicsView::transform(),视图可以转换场景的坐标系。这允许高级导航功能,如缩放和旋转。为了方便起见,qgraphicsView还提供了在视图和场景坐标之间转换的函数:QGraphicsView::mapToScene()和 QGraphicsView::mapFromScene()。
项目(The Item):图形元素
QGraphicsItem是场景中图形项的基类。图形视图为典型形状提供了几个标准项,例如矩形(QGraphicsRectItem)、椭圆(QGraphicsEllipsItem)和文本项(QGraphicsTextItem),但在编写自定义项时,最强大的QGraphicsItem功能可用。除此之外,QGraphicsItem还支持以下功能:
- 鼠标按下、移动、释放和双击事件,以及鼠标悬停事件、滚轮事件和上下文菜单事件;
- 键盘输入焦点和按键事件;
- 拖放;
- 分组,通过父子关系,通过QGraphicsItemGroup;
- 碰撞检测;
项目位于本地坐标系中,与QGraphicsView类似,它还提供许多功能,用于在项目和场景之间以及从项目到项目之间映射坐标。此外,与QGraphicsView一样,它可以使用矩阵:QGraphicsItem::Transform()转换其坐标系。这对于旋转和缩放单个项目很有用。
项可以包含其他项(子项)。父项的转换由其所有子项继承。但是,不管一个项的累积转换如何,它的所有函数(例如,QGraphicsItem::contains()、QGraphicsItem::boundingRect()、QGraphicsItem::collectsWith() 仍在本地坐标中操作。
QGraphicsItem支持通过QGraphicsItem::shape()函数和QGraphicsItem::collipswith() 进行冲突检测,这两个函数都是虚拟函数。通过从QGraphicsItem::shape() 中返回项目的形状作为本地坐标QPaineterPath,QGraphicsItem将为您处理所有冲突检测。但是,如果您希望提供自己的碰撞检测,则可以重新实现QGraphicsItem::CollipsWith()。
Qt图形视图框架中的类
这些类为创建交互式应用程序提供了一个框架。
图形视图坐标系
图形视图基于笛卡尔坐标系;场景中项目的位置和几何图形由两组数字表示:X坐标和Y坐标。使用未转换视图观察场景时,场景中的一个单元由屏幕上的一个像素表示。
注意:由于图形视图使用qt坐标系,因此不支持倒Y轴坐标系(Y向上增长)。
图形视图中有三个有效的坐标系**:项目坐标、场景坐标和视图坐标**。为了简化实现,图形视图提供了方便的功能,允许您在三个坐标系之间进行映射。
渲染时,图形视图的场景坐标对应于QPainer的逻辑坐标,视图坐标与设备坐标相同。后续会说明逻辑坐标和设备坐标之间的关系。
项目坐标
项目在自己的本地坐标系中。它们的坐标通常以中心点(0,0)为中心,这也是所有变换的中心。项目坐标系中的几何基元通常称为项目点、项目线或项目矩形。
在创建自定义项时,只需要担心项坐标;QGraphicsScene和QGraphicsView将为您执行所有转换。这使得实现自定义项非常容易。例如,如果收到一个鼠标按下或拖动输入事件,则事件位置在项目坐标中给出。QGraphicsItem::contains()虚函数,如果某个点在项中,则返回true,否则返回false,在项坐标中接受一个点参数。类似地,项的边界矩形和形状位于项坐标中。
在项目的位置是项目中心点在其父坐标系中的坐标;有时称为父坐标。在这个意义上,场景被视为所有无父项的“父项”。顶层项目的位置在场景坐标中。
子坐标是相对于父坐标的。如果子坐标未转换,则子坐标和父坐标之间的差异与父坐标中项目之间的距离相同。例如:如果未转换的子项精确定位在其父项的中心点,则两个项的坐标系将相同。但是,如果子对象的位置是(10,0),子对象的(0,10)点将对应于其父对象的(10,10)点。
因为项的位置和转换是相对于父项的,所以子项的坐标不受父项的转换的影响,尽管父项的转换隐式转换子项。在上面的例子中,即使父对象被旋转和缩放,子对象的(0,10)点仍然对应于父对象的(10,10)点。但是,相对于场景,子对象将遵循父对象的变换和位置。如果缩放父对象(2x,2x),子对象的位置将位于场景坐标(20,0),其(10,0)点将对应于场景上的点(40,0)。
由于QGraphicsItem::pos()是少数例外之一,因此QGraphicsItem的函数在项坐标中操作,而不考虑项或其任何父项的转换。例如,项目的边界矩形(即QGraphicsItem::boundingRect())总是在项目坐标中给出。场景坐标
场景表示其所有项的基础坐标系。场景坐标系描述了每个顶层项目的位置,也构成了从视图传递到场景的所有场景事件的基础。场景中的每个项目都有一个场景位置和边界矩形(QGraphicsItem::scenePos()和 QGraphicsItem::sceneBoundingRect()),除了其本地项pos和边界矩形之外。场景位置描述了项目在场景坐标中的位置,其场景边界矩形构成了QGraphicsScene如何确定场景的哪些区域已更改的基础。场景中的更改通过QGraphicsScene::changed()信号进行通信,参数是场景矩形的列表。
视图坐标
视图坐标是小部件的坐标。视图坐标中的每个单元对应一个像素。这个坐标系的特殊之处在于它相对于小部件或视区,并且不受观察到的场景的影响。QGraphicsView的视区的左上角始终是(0,0),右下角始终是(视区宽度,视区高度)。所有鼠标事件和拖放事件最初都作为视图坐标接收,您需要将这些坐标映射到场景,以便与项目交互。
坐标映射
在处理场景中的项目时,通常可以将坐标和任意形状从场景映射到项目、从项目映射到项目或从视图映射到场景。例如,在QGraphicsView的视区中单击鼠标时,可以通过调用QGraphicsView::mapToScene(),然后调用QGraphicsScene::ItemAt()来询问场景光标下的项目。如果要知道某个项在视区中的位置,可以对该项调用QGraphicsItem::MapToScene(),然后在视图上调用QGraphicsView::MapFromSecene()。最后,如果要查找视图椭圆中的项目,可以将QPaineterPath传递给mapToScene(),然后将映射的路径传递给QGraphicScene::items()。
通过调用QGraphicsItem::MapToScene()和QGraphicsItem::mapFromScene(),可以将坐标和形状映射到项的场景或从中映射。还可以通过调用QGraphicsItem::mapTopParent()和qgraphicsItem::mapFromParent()映射到项的父项,或者通过调用QGraphicsItem::MapToItem()和QGraphicsItem::mapFromItem()在项之间映射。所有映射函数都可以映射点、矩形、多边形和路径。
视图中有相同的映射函数,可用于映射到场景或从场景映射到场景。QGraphicsView::mapFromSecene()和QGraphicsView::mapToScene()。要从视图映射到项目,首先映射到场景,然后从场景映射到项目。
关键特征
缩放和旋转
QGraphicsView支持与QPainer通过QGraphicsView::setMatrix()进行的相同的仿射转换。通过对视图应用转换,您可以轻松地添加对常见导航功能(如缩放和旋转)的支持。
以下是如何在QGraphicsView子类中实现缩放和旋转插槽的示例:class View : public QGraphicsView { Q_OBJECT ... public slots: void zoomIn() { scale(1.2, 1.2); } void zoomOut() { scale(1 / 1.2, 1 / 1.2); } void rotateLeft() { rotate(-10); } void rotateRight() { rotate(10); } ... };
槽函数可以连接到启用自动重复的QToolButtons。
转换视图时,QGraphicsView保持视图中心对齐。
有关如何实现基本缩放功能的代码,后续会有示例描述。项目组
通过使一个项目成为另一个项目的子项目,您可以实现项目分组最基本的特性:
- 项目将一起移动
- 所有转换都从父项目传播到子项目。
此外,QGraphicsItemGroup是一个特殊的项,它将子事件处理与用于向组中添加和删除项的有用接口结合在一起。将项添加到QGraphicsItemGroup将保留该项的原始位置和转换,而通常重新设置项将导致子项相对于其新父项重新定位自身。为了方便起见,可以通过调用QGraphicScene::CreateItemGroup()通过场景创建QGraphicsItemGroups。
小部件和布局
Qt4.4通过QGraphicsWidget引入了对几何和布局感知项的支持。这个特殊的基项类似于QWidget,但与QWidget不同,它不是从QPaintDevice继承的,而是从QGraphicsItem继承的。这允许您编写带有事件、信号和槽、大小提示和策略的完整小部件,还可以通过QGraphicsLinearLayout和QGraphicsGridLayout在布局中管理小部件的几何图形。
QGraphicsWidget
基于QGraphicsItem的功能和精简的占地面积,QGraphicsWidget提供了两个方面的最佳功能:QWidget的额外功能,例如样式、字体、调色板、布局方向及其几何图形,以及QGraphicsItem的分辨率独立性和转换支持。因为图形视图使用实坐标而不是整数,所以QGraphicsWidget的几何函数也在QRectF和QPointF上运行。这也适用于框架矩形、边距和间距。例如,对于QGraphicsWidget,指定内容页边距(0.5、0.5、0.5、0.5)并不少见。您可以创建子窗口和“顶级”窗口;在某些情况下,您现在可以为高级MDI应用程序使用图形视图。
一些QWidget的属性是受支持的,包括窗口标志和属性,但不是全部。参考QGraphicsWidget的类文档,以全面了解什么是受支持的,什么是不受支持的。例如,可以通过将Qt::window标志传递给QGraphicsWidget的构造函数来创建装饰窗口,但图形视图当前不支持MacOs上常见的Qt::Sheet和Qt:: Drawer标志。QGraphicsLayout
QGraphicsLayout是专门为QGraphicsWidget设计的第二代布局框架的一部分。它的API与QLayout非常相似。您可以在QGraphicsLinearLayout和QGraphicsGridLayout中管理小部件和子布局。您还可以通过自己对QGraphicsLayout子类化来轻松地编写自己的布局,或者通过编写QGraphicsLayoutItem的适配器子类,将自己的QGraphicsItem项添加到布局中。
嵌入式小部件支持
图形视图为在场景中嵌入任何小部件提供无缝支持。您可以嵌入简单的小部件,如QLineEdit或QPushButton,复杂的小部件,如QTabWidget,甚至完整的主窗口。要将小部件嵌入到场景中,只需调用QGraphicScene::AddWidget(),或创建QGraphicsProxyWidget实例手动嵌入小部件。
通过QGraphicsProxyWidget,图形视图能够深入集成客户端小部件的功能,包括其光标、工具提示、鼠标、平板电脑和键盘事件、子小部件、动画、弹出窗口(如QComboBox或QCompeter),以及小部件的输入焦点和激活。QGraphicsProxyWidget甚至集成了嵌入式小部件的选项卡顺序,这样您就可以在嵌入式小部件中插入和取出选项卡。甚至可以将新的QGraphicsView嵌入到场景中,以提供复杂的嵌套场景。
当转换嵌入的小部件时,图形视图确保小部件独立地转换分辨率,允许字体和样式在放大时保持清晰。(请注意,分辨率独立性的效果取决于样式。)
性能
浮点指令
为了准确、快速地对项目应用转换和效果,在假设用户的硬件能够为浮点指令提供合理性能的前提下,构建了图形视图。
许多工作站和台式计算机都配备了适当的硬件来加速这种计算,但是一些嵌入式设备可能只提供库来处理数学运算或模拟软件中的浮点指令。
因此,某些类型的影响在某些设备上可能比预期的慢。可以通过在其他区域进行优化来补偿这种性能损失;例如,使用OpenGL渲染场景。但是,如果这些优化还依赖于浮点硬件的存在,那么它们本身可能会导致性能降低。
上一篇:无
下一篇:《Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解》
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/115791408 -
qt视图框架_列表视图框架
2020-09-13 16:07:20qt视图框架Unity Asset Store packageand aUnity Asset Store软件包和开发人员社区的public repositoryfor the developer community.公共资源库获得。 Project Carte Blanche(PCB) is Unity Lab’s research ... -
基于QT图形视图框架的PLC梯形图编辑器的设计.pdf
2021-08-07 15:03:59#资源达人分享计划# -
【翻译】Qt模型视图框架介绍(长文)
2021-07-25 14:39:21Qt 包含一组项目视图类,这些类使用模型/视图框架来管理数据之间的关系以及数据呈现给用户的方式。 模型-视图-控制器 (MVC)设计模式,通常在构建用户界面时使用。 MVC 由三种对象组成。 Model 是应用程序对象 ... -
【翻译 + 整理】Qt图形视图框架概述
2021-05-17 23:57:381、图形视图框架提供了一个用于管理大量定制的二维图形项目并与之交互的界面,以及一个用于可视化项目的视图,并支持缩放和旋转。 2、图形视图框架包括一个事件传播体系结构,允许对场景中的项目提供精确的双精度... -
QT图形与视图框架(最基础篇)
2017-11-08 10:38:55QT图形与视图框架QT图形与视图框架QT图形与视图框架QT图形与视图框架 -
Qt 视图框架示例 Colliding Mice 的翻译
2020-06-10 10:27:13目录名字Qt 视图框架示例 Colliding Mice 的翻译简介:Mouse Class 定义Mouse Class 定义The Main() 函数 Qt 视图框架示例 Colliding Mice 的翻译 简介: 该示例程序介绍了怎样在Qt的视图框架里创建动画以及冲突检测... -
Qt5之图形视图框架
2021-12-17 20:56:35图形视图框架提供了一个基于图形项的模型视图编程方法 组成三元素:场景(QGraphicsScene类)、视图(QGraphicsView类)、图形项(QGraphicsItem类)。 多个视图可以看到同一个场景,场景包含各种各样的几何形状的... -
Qt 之图形视图框架
2016-07-20 16:59:13简述图形视图(Graphics View)提供了一个用于管理和交互大量自定义的二维图形对象(Item),以及一个支持缩放和旋转操作的视图部件用于显示这些视图项。框架包括一个事件传播架构,支持scene中的items进行精确的双... -
视频教程-Qt图形视图框架详解-其他
2020-05-28 10:24:00Qt图形视图框架详解 十余年开发经验,5年Qt使用经验,在网络机顶盒、智能机... -
74 QT图形视图框架(Graphics View)
2019-05-11 23:07:57(1)Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。 (2)Graphics View支持事件传播体系结构,可以使图元在场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和... -
Qt 图形视图框架 (一)
2018-07-12 14:52:16如果要绘制成千上万的图形,并且对它们进行控制,比如拖动这些图形、检测它们的位置以及判断它们是否碰撞等,可以使用Qt提供的图形视图框架来进行设计。 图形视图框架提供了一个基于图形项的模型视图编程方法,主要... -
【QT】图形视图、动画框架
2022-03-29 09:21:28Qt图形视图框架、动画框架 Qt提供了图形视图框架(GraphicsView Framework)、动画框架(The Animation Framework)、状态机框架(The State Machine Framework)来实现更加高级的图形与动画应用。使用这些框架可以... -
QT图形视图框架显示SVG文件
2020-11-12 14:11:02一个C++语言编写的测试demo,Qt5.9可编译运行。可作为学习Qt图形视图显示,或SVG二次开发的初步了解 -
QT 图形视图框架(1)
2020-08-05 09:28:04图形视图框架提供了一个基于图形项的模型视图编程方法,主要由场景(QGraphicsScene)、视图(QGraphicsView)和项(QGraphicsItem)三部分组成。多个视图可以查看一个场景,场景中包含各种各样几何形状的图形项。 场景 ... -
QT图形视图框架(The Graphics View Framework)详细介绍
2013-06-18 11:56:03详解介绍Qt中视图框架机制及场景中主要的常用函数作用及用法,是学习者可以对Qt的场景视图有深入的了解。 -
Qt视图框架QGraphicsView
2020-05-21 17:00:28Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能; Graphics View支持事件传播体系结构,可以使图元在场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标事件。... -
Qt视图框架坐标
2018-06-25 00:45:52qt的图形试图框架提供基于图元的模型视图编程,功能非常强大。1.图形视图的事件传递:View-------------->Scene--------------->Item事件先传给View,然后View传给Scene,最后Scene传给Item2.坐标系统... -
基于Qt5图形视图框架的俄罗斯方块
2016-01-29 14:53:20基于Qt5的图形视图框架的俄罗斯方块的实现,可以参照博客:http://blog.csdn.net/sxpsxp12/article/details/50607224 -
qt之图形视图框架(上)
2017-05-12 15:33:50转载自:https://wizardforcel.gitbooks.io/qt-beginning/content/24.html 导语 在前面讲的基本绘图中,我们可以自己绘制各种图形,并且控制它们。但是,如果需要同时绘制很多个相同或不同的图形,并且要控制...