首页 > 其他分享 >Qt 图形视图框架<三>——<坐标系统>

Qt 图形视图框架<三>——<坐标系统>

时间:2023-09-07 23:44:40浏览次数:51  
标签:场景 Qt 视图 坐标系 坐标 图形 QGraphicsItem

Qt 图形视图框架<三>——<坐标系统>

 

一 基础知识 

  图形视图框架是基于笛卡尔坐标系统的,一个图形项在场景中的位置和几何形状由x坐标和y坐标来表示。当使用一个没有变换的视图来观察场景时,场景中的一个单元代表屏幕上的一个像素。图形视图框架的三个坐标系分别是视图坐标系、场景坐标系和图元坐标系。三个坐标系分别由视图、场景和图元使用。为了方便应用,图形视图框架中提供了一些便捷函数来完成3个坐标系统之间的映射。当进行绘图时,场景坐标对应QPainter的逻辑坐标,视图坐标对应设备坐标。

  比如在给场景中添加图元时,图元的位置就是相对于场景坐标系而言的:

 1.1 场景坐标系

  场景坐标系是所有图元对象的绝对坐标. 有四个象限,场景坐标是所有图形项的基础坐标系统。场景坐标系统描述了每一个顶层图形項的位置,也形成了所有从视图传到场景上的事件的基础。场景坐标的原点在场景的中心,x轴正方向向右,y轴正方向向下。

  每一个在场景中的图形项除了拥有一个图形項的本地坐标和边界矩形外,还都拥有一个场景坐标(QGraphicsItem: :scenePos())和一个场景中的边界矩形(QGraphicsItem::sceneBoundingRect())。场景坐标用来描述图形项在场景坐标系统中的位置,而图形项的场景边界矩形用于QGraphicsScene判断场景中的哪些区域进行了更改。

常用添加图元函数:

QGraphicsScene::setBackgroundBrush   //填充背景色

QGraphicsScene::setForegroundBrush   //填充前景色

QGraphicsScene::addSimpleText        //添加简单文本

QGraphicsScene::addLine //添加直线

QGraphicsScene::addRect //添加矩形

QGraphicsScene::addEllipse //添加椭圆

QGraphicsScene::addWidget //添加窗口

QGraphicsScene::addPixmap //添加图片

操作图元函数:

QGraphicsScene::itemAt //查找场景某个中最表层的item

QGraphicsScene::setSelectionArea   //设置选定区域

QGraphicsScene::setSceneRect         //设置场景的区域大小

QGraphicsScene::itemsBoundingRect    //根据所有的item计算区域大小

QGraphicsScene:: selectedItems //获取被选中的item,item必须为可选QGraphicsItem::ItemIsSelectable

QGraphicsScene类的坐标系以中心为原点(0,0),如下图所示。

1.2 视图坐标

  视图的坐标就是窗口部件的坐标。视图坐标的每一个单位对应一个像素。QGraphicsView视图的左上角是(0,0),x轴正方向向右,y轴正方向向下。

  所有的鼠标事件最开始都是使用视图坐标。 QGraphicsView类继承自QWidget类,因此它与其他的QWidget类一样,以窗口的左上角作为自己坐标系的原点,如图所示。

1.3 图形项坐标

  图形项使用自己的本地坐标,这个坐标系统通常以图形项中心为原点,这也是所有变换的原点。图形项坐标方向是x轴正方向向右,y轴正方向向下。创建图形项后,只需注意图形项坐标就可以了,QGraphicsScene和QGraphicsView会完成所有的变换。

  一个item的位置是item坐标系下的中心点在其父对象坐标系下的位置,有时也被称为父坐标。对于所有没有父对象的对象来说,场景就是其父对象。因此最顶层items的位置就是其在scene中的位置。

  子对象坐标系是相对于父对象坐标系来说的一个概念。如果子节点没有进行矩阵变换,那么在子对象坐标系和父对象坐标系的差异就和这些对象在父对象中的偏移一样。比如:如果一个未经变换的子对象精确的位于父对象的中心点,那么这两个对象的坐标系就是完全一致的。如果子对象的位置是(10, 0),那么子对象的(0, 10)点就位于父对象的(10, 10)点的位置。

  由于items的位置和转换是相对于父对象来说的,因此虽然父对象的变换隐式地变换了子对象,子对象的坐标系不会因父对象坐标系改变而改变。在上面的例子中,即使父对象经过了旋转和缩放,子对象的(0, 10)点依然相对于父对象是(10, 10)点。不过相对于scene来说,子对象将随着父对象进行变换和偏移 。如果父对象缩放了(2x, 2x),那么子对象在场景坐标系下将会位于(20, 0)的位置,同时其(10, 0) 点将会对应于场景中的(40, 0)点。

  不管item或父对象进行了什么样的变化, QGraphicsItem的函数一般总是表示在item坐标系下的位置,其操作也作用于item坐标系内。比如:一个对象的矩形边界(QGraphicsItem::boundingRect())总是在item坐标系下给出的。但是QGraphicsItem::pos()是例外之一,该函数表示其在父对象中的位置 。

QGraphicsItem::rect //不带边框的图形区域 
QGraphicsItem::boundingRect         //带边框的图形区域
QGraphicsItem::collidesWithItem     //碰撞检测
QGraphicsItem::setScale                 //缩放
QGraphicsItem::setRotation              //旋转
QGraphicsItem::setZValue             //设置z坐标,图元的叠加先后顺序可以用它来设置
QGraphicsItem::setPos               //设置位置坐标

设置item的属性:

void QGraphicsItem::setFlags(GraphicsItemFlags flags);
/*
*参数GraphicsItemFlags flags 为枚举类型,可以以下值
* QGraphicsItem::ItemIsMovable 是否可以移动
* QGraphicsItem::ItemIsSelectable 是否可以被选中
* QGraphicsItem::ItemIsFocusable 是否可以设置为焦点item
*/

  QGraphicsItem类的坐标系,若在调用QGraphicsItem类的paint()函数重绘图元时,则以此坐标系为基准,如下图所示。

 

二 、 坐标映射转换

  当处理场景中的图形项时,将坐标或者一个任意的形状从场景映射到图形项、或者从一个图形项映射到另一个图形项、或者从视图映射到场景,这些坐标变换都是非常有用的。例如:

  • 当在QGraphicsView的视口上单击了鼠标,便可以调用QGraphics­View::mapToScene()以及 QGraphicsScene::itemAt()来获取光标下的图形项;
  • 如果要获取一个图形项在视口中的位置,那么可以先在图形项上调用QGraphicsItem::mapToScene(),然后在视图上调用QGraphicsView: :mapFromScene();如果要获取在视图的一个椭圆形中包含的图形项,可以先传递一个QPainterPath对象作为参数给mapToScene()函数,然后传递映射后的路径给QGraphicsScene::items()函数。

不仅可以在视图、场景和图形项之间使用坐标映射,还可以在子图形项和父图形项或者图形项和图形项之间进行坐标映射 。图形视图框架提供的所有映射函数如下表所列,所有的映射函数都可以映射点、矩形、多边形和路径。

映 射 函 数转 换 类 型
QGraphicsView::mapToScene() 视图到场景
QGraphicsView::mapFromScene() 场景到视图
QGraphicsItem:: mapFromScene() 场景到图形项
QGraphicsItem:: mapToScene() 图形项到场景
QGraphicsItem:: mapToParent() 子图形项到父图形项
QGraphicsItem:: mapFromParent() 父图形项到子图形项
QGraphicsItem:: mapToItem() 本图形项到其他图形项
QGraphicsItem:: mapFromItem() 其他图形项到本图形项

调整坐标系的的类是QTransform、QMatrix,这两个类都提供了缩放、旋转、变形坐标系的方法。

2.1 调整QGraphicsVeiw坐标系

复制代码
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QLabel>
#include <QTransform>
​
int main(int argc, char** argv)
{
   QApplication app(argc, argv);
   QGraphicsView view;
   QGraphicsScene scene;
   view.setScene(&scene);
   view.show();
   view.resize(400, 400);
   QTransform transform;
​
   //transform.translate(100, 0); //移动坐标原点
   transform.scale(1.5, 1);  //缩放
   //transform.rotate(10);   //旋转
  // transform.shear(0.1, 0.1); //变形
​
   view.setTransform(transform);
​
/*添加矩形*/
scene.addRect(0, 100, 100, 100, QPen(Qt::yellow), QBrush(Qt::blue));
   return app.exec();
}
复制代码

2.2 调整QGraphicsItem坐标系

复制代码
#include <QApplication>
#include <QGraphicsView>
#include <QTransform>
#include <QGraphicsRectItem>
​
int main(int argc, char** argv)
{
   QApplication app(argc, argv);
   QGraphicsView view;
   QGraphicsScene scene;
   view.setScene(&scene);
   view.show();
   view.resize(400, 400);
   QTransform transform;
​
   //transform.translate(100, 0); //移动坐标原点
   transform.scale(1.5, 1);  //缩放
   //transform.rotate(10);   //旋转
  // transform.shear(0.1, 0.1); //变形
   /*添加矩形*/
   QGraphicsRectItem *rect = scene.addRect(0, 100, 100, 100
                                , QPen(Qt::yellow),  QBrush(Qt::blue));
​
   rect->setTransform(transform);
​
   return app.exec();
}
复制代码 作者:灼光 出处:https://www.cnblogs.com/laiyingpeng 本博客文章大多为原创,转载请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。   分类: Qt 好文要顶 关注我 收藏该文  灼光
粉丝 - 13 关注 - 1     +加关注 1 0       « 上一篇: Qt 图形视图框架<二>——<QGraphicsView、QGraphicsScene>
» 下一篇: QML Canvas 2D绘图<上> posted @ 2020-02-12 18:15  灼光  阅读(3341)  评论(1)  编辑  收藏  举报    

 

 

 

from:  https://www.cnblogs.com/laiyingpeng/p/12299502.html

标签:场景,Qt,视图,坐标系,坐标,图形,QGraphicsItem
From: https://www.cnblogs.com/im18620660608/p/17686385.html

相关文章

  • Qt5.9 Graphics View 最简单制作画图
    话不多说先看程序的效果图: 这个也算是一个基础的制作,下面带大家来看看如合制作吧。首先,从QGraphicsView类继承定义一个图形视图类QWGraphicsView。qwgraphicsview.h#ifndefQWGRAPHICSVIEW_H#defineQWGRAPHICSVIEW_H #include<QObject>#include<QGraphicsView>/......
  • Qt QListView添加数据
    QListView添加数据准备数据QStringListlist;list<<"数据1"<<"数据2";准备模型QStringListModel*model;model=newQStringListModel(this);将数据添加到模型中model->setStringList(list);为QListView添加数据模型ui->listView->setMode......
  • Qt图形视图框架事件传递顺序
     全文链接:http://www.fearlazy.com/index.php/post/111.html Qt为我们提供的图形视图框架真的是非常好用,它通过分解出视图、场景和图元降低了我们绘制图形的难度。它提供了强大图元控制能力,如快速查找图元、检测图元位置、检测图元碰撞等。除此以外图形视图框架还有一个很强大......
  • qt程序调用cuda-11.7,cmake编译时,提示:"CMakeCUDACompilerId.cu" failed. Compiler:
    报错显示:Running/home/wc/software/cmake-3.26.3-linux-x86_64/bin/cmake/home/wc/work/junke_src/missile-sim'-GCodeBlocks-UnixMakefiles'in/home/wc/work/junke_src/build/debug.CMakeErrorat/home/wc/software/cmake-3.26.3-linux-x86_64/share/cmak......
  • nicegui:Python 图形界面库,简单好用
    前言在现代计算机应用程序开发中,图形用户界面(GUI)是用户与程序交互的重要组成部分。然而,GUI开发往往需要大量的代码和复杂的布局,给开发者带来了一定的挑战。在本篇博文中,将介绍nicegui,它是一个简单易用的图形用户界面库,提供了一种简化GUI开发的方式,使开发者能够更快速地构建吸......
  • Qt QDateTime类型加减计算
    在Qt框架中,QDateTime类提供了一系列可以进行日期和时间的加减计算的方法,可用于处理日期和时间相关的问题。一些常用的方法如下:1.QDateTime::addDays(intdays):在当前时间的基础上增加指定天数后的日期和时间。1QDateTimecurrentDateTime=QDateTime::currentDateTime();2Q......
  • QT QDateTime 计算两个日期时间差
    1、计算两个日期天数差1QDateTimetime1=QDateTime::fromString("2020-11-2616:40:02","yyyy-MM-ddhh:mm:ss");2//QDateTimetime2=QDateTime::fromString("2020-11-2616:43:02","yyyy-MM-ddhh:mm:ss");3QDateTimetime2=QD......
  • oracle 对物化视图的使用中遇到问题
    1.建立一个简单的物化视图createtablestudent_info(snonumber(10)constraintpk_si_snoprimarykey,snamevarchar2(10),sexvarchar2(2),create_datedate);CREATEMATERIALIZEDVIEWmv_student_infoBUILDIMMEDIATEREFRESHF......
  • RK3568开发笔记(七):在宿主机ubuntu上搭建Qt交叉编译开发环境,编译一个Demo,目标板运行Demo
    前言  在之前的博文中已经搭建好了一个比较完善的ubuntu宿主机,都很完善了但是发现没有Qt交叉编译开发环境,所以还需要搭建一套Qt交叉编译开发环境。<br>补充说明  本篇是基于《RK3568开发笔记(三):RK3568虚拟机基础环境搭建之更新源、安装网络工具、串口调试、网络连接、文件传......
  • RK3568开发笔记(七):在宿主机ubuntu上搭建Qt交叉编译开发环境,编译一个Demo,目标板运行Demo
    前言  在之前的博文中已经搭建好了一个比较完善的ubuntu宿主机,都很完善了但是发现没有Qt交叉编译开发环境,所以还需要搭建一套Qt交叉编译开发环境。 补充说明  本篇是基于《RK3568开发笔记(三):RK3568虚拟机基础环境搭建之更新源、安装网络工具、串口调试、网络连接、......