图形视图框架的坐标

图形视图基于笛卡尔坐标系;项目在场景中的位置和几何图形由两组数字表示:X 坐标和 Y 坐标。使用未变换的视图观察场景时,场景上的一个单元由屏幕上的一个像素表示。

图形视图中有三种有效的坐标系:

  • 项目坐标
  • 场景坐标
  • 视图坐标

为了简化实现图形视图提供了三个坐标系之间进行映射。

项目的坐标:

项目位于其自己的局部坐标系中。它们的坐标通常以中心点 (0, 0) 为中心,这也是所有变换的中心。项目坐标系中的几何基元通常称为项目点、项目线或项目矩形。

创建自定义项目时,您只需担心项目坐标;QGraphicsScene 和 QGraphicsView 将为您执行所有转换。这使得实现自定义项变得非常容易。

项目位置是项目在其父坐标系中的中心点的坐标;有时称为坐标。从这个意义上说,这个场景被视为所有无父母项目的“父母”。顶级物品的位置位于场景坐标中。

子坐标相对于父坐标。如果子坐标未变换,则子坐标和父坐标之间的差异与父坐标中项目之间的距离相同。例如:如果未转换的子项精确定位在其父项的中心点,则这两个项的坐标系将相同。但是,如果子项的位置是 (10, 0),则子项的 (0, 10) 点将对应于其父项的 (10, 10) 点。

由于项的位置和转换相对于父项,因此子项的坐标不受父项转换的影响,尽管父项的转换隐式变换了子项。在上面的示例中,即使父级旋转和缩放,子项的 (0, 10) 点仍将对应于父项的 (10, 10) 点。然而,相对于场景,孩子将跟随父母的转变和位置。如果父项缩放 (2x, 2x),则子项的位置将位于场景坐标 (20, 0),其 (10, 0) 点将与场景中的点 (40, 0) 相对应。

场景坐标:

场景表示其所有项目的基本坐标系。场景坐标系描述每个顶级项目的位置,也构成了从视图传递到场景的所有场景事件的基础。

  • 项目可以使用 scenePos()来查看在场景的位置
  • 项目使用sceneBoundingPect()来查看场景的边界矩形
  • 场景中的变化使用QGraphicsScene::changed()信号进行通信

视图坐标:

视图的坐标是部件的坐标,视图坐标的每一个单位对应一个像素,原点为(0,0)总是在QGraphicsView视口的左上角,所有的鼠标事件和拖放事件最初都是使用视图视图坐标接收。

例子:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(-200,-200,400,400);//创建一个场景
    QGraphicsRectItem item1(0,0,100,100);//创建一个圆
    item1.setPos(0,0);//设置位置
    scene.addItem(&item1);
    QGraphicsView view2;//创建第一个视图
    view2.setScene(&scene);//设置场景
    view2.resize(400,400);
    view2.show();//显示
    return a.exec();
}

 场景和视图的关系:

场景:

QGraphicsScene scene(-200,-200,400,400);//创建一个场景

这段代码代表的是该场景是从(-200,-200)到(400,400)的一个矩形

视图:

    QGraphicsView view2;//创建第一个视图
    view2.setScene(&scene);//设置场景
    view2.resize(400,400);//重置视图大小
    view2.show();//显示

场景和项目的关系:

  • 如果没设置位置的话,项目的(0.0)点会放置在场景的(0,0)点
  • 可以使用setPos()修改项目在视图中的位置

修改场景: 

例一:场景为QRectF(0,0,400,400),项目为(0,0,100,100)

    QGraphicsScene scene(0,0,400,400);//创建一个场景
    QGraphicsRectItem item1(0,0,100,100);//创建一个矩形
    scene.addItem(&item1);
    //视图部分省略

由于项目的起始点为(0,0 ),默认放到场景的位置为(0,0)

 例二:场景为QRectF(-200,-200,400,400),项目为(0,0,100,100)

    QGraphicsScene scene(-200,-200,400,400);//创建一个场景
    QGraphicsRectItem item1(0,0,100,100);//创建一个矩形
    scene.addItem(&item1);

 使用setPos()修改位置

    QGraphicsScene scene(-200,-200,400,400);//创建一个场景
    QGraphicsRectItem item1(0,0,100,100);//创建一个矩形
    scene.addItem(&item1);
    item1.setPos(-200,-200);//把位置设置为-200,-200

 修改项目:

例一:场景为QRectF(0,0,400,400),项目为(-50,-50,100,100)

将项目中的(0,0)点放到场景中的(0,0)点,由于项目的起始坐标为(-50,-50)宽高为(100,100),所以(0,0)点为项目的中心点

    QGraphicsScene scene(0,0,400,400);//创建一个场景
    QGraphicsRectItem item1(-50,-50,100,100);//创建一个矩形
    scene.addItem(&item1);

使用setPos()设置位置

    QGraphicsScene scene(0,0,400,400);//创建一个场景
    QGraphicsRectItem item1(-50,-50,100,100);//创建一个矩形
    scene.addItem(&item1);
    item1.setPos(50,50);//把位置设置为50,50

 

坐标的映射:

在处理场景中的项时,将坐标和任意形状从场景映射到项、从项映射到项或从视图映射到场景非常有用。

当你在QGraphicsView中点击鼠标时,可以通过QGraphicsView::mapToScene(),以及QGraphicsScene::itemAt()来获取光标下的图型项,获取在视图的一个椭圆形中包含的图形项,先传递一个QPainterPath参数给mapToScence()函数,然后传递映射后的路径给QGraphicsScene::items()函数。

图形视图框架中的映射函数:

QGraphicsView::mapToScence()从视图坐标系统映射到场景坐标系统
QGraphicsView::mapFromScene()从场景坐标系统映射到视图坐标系统
QGraphicsItem::mapToScene()从图形项的坐标系统映射到场景坐标系统
QGraphicsItem::mapToParent()从本图形项的坐标系统映射到其父图形项的坐标系统
QGraphicsItem::mapFromParent()从父图形项的坐标系统映射到本图形项的坐标系统
QGraphicsItem::mapToItem()从本图形项的坐标系统映射到另一个图形项坐标系统
QGraphicsItem::mapFromItem()从另一个图形项的坐标系统到本场景坐标系统

例子:

创建一个C++文件,继承自QGraphicsView,并重写鼠标点击事件

#ifndef MYVIEW_H
#define MYVIEW_H
#include<QGraphicsItem>
#include<QGraphicsView>
#include<QGraphicsScene>
#include<QMouseEvent>
#include<QDebug>

class MyView:public QGraphicsView
{
public:
    MyView();
    void mousePressEvent(QMouseEvent *event);//鼠标点击事件
};

#endif // MYVIEW_H




#include "myview.h"

MyView::MyView()
{

}

void MyView::mousePressEvent(QMouseEvent *event)//鼠标点击事件
{
    QPoint viewPos=event->pos();//获取鼠标在视图中的位置
    qDebug()<<"viewPos:"<<viewPos;
    QPointF scenePos=mapToScene(viewPos);//用视图位置获取在场景的位置
    qDebug()<<"scenePos:"<<scenePos;
    QGraphicsItem *item=scene()->itemAt(scenePos,QTransform());//获取该位置的项目
    if(item)
    {
        QPointF itemPos=item->mapFromScene(scenePos);//获取项目在场景中的位置
        qDebug()<<"itemPos:"<<itemPos;
    }

}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(-200,-200,400,400);//创建一个场景
    QGraphicsEllipseItem item1(50,50,100,100);//圆项目
    scene.addItem(&item1);

    MyView view;//创建视图
    view.setScene(&scene);//添加场景
    view.show();
    return a.exec();
}

点击圆项目:

项目的堆叠顺序:

在QGraphicsItem中可以使用 setZValue()函数来设置堆叠的优先级,数值越大优先级越高,默认为0。

注意:优先级相同的话,后绘制的图形会覆盖先绘制的图形

优先级相同的情况: 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(0,0,400,400);//创建一个场景
    QGraphicsEllipseItem item1(50,50,100,100);//圆项目
    item1.setBrush(QColor(Qt::red));//红色
    scene.addItem(&item1);
    QGraphicsEllipseItem item2(75,75,100,100);//圆项目
    item2.setBrush(QColor(Qt::blue));//蓝色
    scene.addItem(&item2);

    QGraphicsView view;
    view.setScene(&scene);//添加场景
    view.show();
    return a.exec();
}

 设置覆盖优先级:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(0,0,400,400);//创建一个场景
    QGraphicsEllipseItem item1(50,50,100,100);//圆项目
    item1.setBrush(QColor(Qt::red));
    item1.setZValue(1);//设置覆盖优先级
    scene.addItem(&item1);
    QGraphicsEllipseItem item2(75,75,100,100);//圆项目
    item2.setBrush(QColor(Qt::blue));
    scene.addItem(&item2);

    QGraphicsView view;
    view.setScene(&scene);//添加场景
    view.show();
    return a.exec();
}

设置父项目:

QGraphicsItem可以设置父项目,使用setParentItem()函数可以将一个项设置成另一个项的父项。如果此项目已有父项,则首先将其从上一个父项中删除。

parentItem()返回父项
parentObject()返回指向项的父项的指针,强制转换为 QGraphicsObject
parentWidget()返回指向项的父构件的指针。项目的父微件是最接近的父微件
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(0,0,400,400);//创建一个场景
    QGraphicsEllipseItem item1(75,75,100,100);//圆项目
    item1.setBrush(QColor(Qt::red));
    scene.addItem(&item1);
    QGraphicsEllipseItem item2(75,75,200,200);//圆项目
    item2.setBrush(QColor(Qt::blue));
    scene.addItem(&item2);

    item1.setParentItem(&item2);//设置父项

    QGraphicsView view;
    view.setScene(&scene);//添加场景
    view.show();
    return a.exec();
}

视图的中心:

当场景很大时,可以使用QGraphicsView中的centerOn()函数来设置场景中的一个点或一个图形项作为视图的显示中心

未设置中心:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(-200,-200,800,800);//创建一个场景
    QGraphicsEllipseItem item1(75,75,100,100);//圆项目
    item1.setBrush(QColor(Qt::red));
    scene.addItem(&item1);

    QGraphicsView view;
    view.setScene(&scene);//添加场景
    //view.centerOn(&item1);//设置中心图形项
    view.resize(400,400);
    view.show();
    return a.exec();
}

 设置中心后:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(-200,-200,800,800);//创建一个场景
    QGraphicsEllipseItem item1(75,75,100,100);//圆项目
    item1.setBrush(QColor(Qt::red));
    scene.addItem(&item1);

    QGraphicsView view;
    view.setScene(&scene);//添加场景
    view.centerOn(&item1);//设置中心图形项
    view.resize(400,400);
    view.show();
    return a.exec();
}

参考文档:

Graphics View Framework | Qt Widgets 5.15.13

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/1519.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opencv仿射变换之获取变换矩阵

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

JavaSe第10次笔记

1.Java中&#xff0c;static不能修饰局部变量。 2.构造代码块&#xff1a;可用于成员变量的赋值&#xff0c;但需要注意的是&#xff0c;构造代码块最先执行(比构造方法先)。 3.静态代码块(可用于静态成员变量赋值)&#xff1a;写法如下 static { 静态成员操作; } (比构造…

Python逆向及相关知识

今天第二次看见python字节码的逆向题&#xff0c;然后发现了一个介绍Python逆向的文章&#xff0c;所以把文章里的内容简单整理记录一下。 文章参考&#xff1a;https://www.cnblogs.com/blili/p/11799398.html Python运行原理&#xff1a; 一.什么是Python Python 是一种解…

ChatGPT加强版GPT-4面世,打工人的方式将被颠覆

&#x1f517; 运行环境&#xff1a;chatGPT&#xff0c;GPT-4 &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#…

推荐一款卸载软件的小工具-《UninstallToo》

目录 UninstallToo介绍 UninstallToo下载 UninstallToo使用 总结 UninstallToo介绍 Uninstall Tool 是一款可以用来替代“添加/删除程序”的工具。它允许您显示隐藏的安装程序&#xff0c;按名称过滤已安装程序的列表&#xff0c;强行写在程序&#xff0c;浏览注册表项目&a…

【Vue】Vue的安装

&#x1f3c6;今日学习目标&#xff1a;Vue3的安装 &#x1f603;创作者&#xff1a;颜颜yan_ ✨个人格言&#xff1a;生如芥子&#xff0c;心藏须弥 ⏰本期期数&#xff1a;第一期 &#x1f389;专栏系列&#xff1a;Vue3 文章目录前言Vue3安装独立版本CDN安装第一个Vue程序总…

元数据管理实践数据血缘

元数据管理实践&数据血缘 什么是元数据&#xff1f;元数据MetaData狭义的解释是用来描述数据的数据&#xff0c;广义的来看&#xff0c;除了业务逻辑直接读写处理的那些业务数据&#xff0c;所有其它用来维持整个系统运转所需的信息&#xff0f;数据都可以叫作元数据。比如…

训练自己的GPT2-Chinese模型

文章目录效果抢先看准备工作环境搭建创建虚拟环境训练&预测项目结构模型预测续写训练模型遇到的问题及解决办法显存不足生成的内容一样文末效果抢先看 准备工作 从GitHub上拉去项目到本地&#xff0c;准备已训练好的模型百度网盘&#xff1a;提取码【9dvu】。 gpt2对联训…

10.0自定义SystemUI下拉状态栏和通知栏视图(六)之监听系统通知

1.前言 在进行rom产品定制化开发中,在10.0中针对systemui下拉状态栏和通知栏的定制UI的工作开发中,原生系统的下拉状态栏和通知栏的视图UI在产品开发中会不太满足功能, 所以根据产品需要来自定义SystemUI的下拉状态栏和通知栏功能,首选实现的就是下拉通知栏左滑删除通知的部…

【12】SCI易中期刊推荐——计算机信息系统(中科院4区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…

SpringCloudAlibaba配置中心: nacos-config

nacos-config配置中心 本项目代码与笔记已存放在Gitee仓库 地址&#xff1a; 代码&#xff0c;笔记 文章目录nacos-config配置中心1.1 快速开始1.2 搭建nacos-config服务1.3 Config相关配置1.3.1 支持profile粒度的配置示例&#xff1a;1.3.2 支持命名空间分类配置(按环境规类…

【批处理】- 批处理自动安装Mysql与Redis

前言 在全新环境中安装MySQL与Redis操作是挺麻烦的&#xff0c;于是就想使用脚本来自动安装&#xff0c;使用批处理进行一步到位的安装&#xff0c;后面还能使用工具进行打包成exe可执行文件&#xff0c;一键安装&#xff0c;最后能够更好的部署项目到windows系统的服务器。 …

READ: Large-Scale Neural Scene Rendering for Autonomous Driving

READ: Large-Scale Neural Scene Rendering for Autonomous Driving &#xff1a;面向自动驾驶的大规模神经场景绘制 门卷积 https://www.jianshu.com/p/09fc8490104d https://blog.csdn.net/weixin_44996354/article/details/117409438摘要&#xff1a;论文提出了一种大规模神…

vue2前端实现html导出pdf功能

1. 功能实现方案 1.html转换成canvas后生成图片导出pdf&#xff08;本文选用&#xff09; html转canvas插件&#xff1a;html2canvas是一款将HTML代码转换成Canvas的插件&#xff1b;canvas生成pdf&#xff1a;jsPDF是一个使用Javascript语言生成PDF的开源库 2.HTML代码转出…

【剑指offer】10~11.斐波那契数列(C# 实现)

文章目录前言关于编译环境10- I. 斐波那契数列10- II. 青蛙跳台阶问题11. 旋转数组的最小数字结语前言 &#x1f340; 大家好&#xff0c;我是哈桑。这是自己的 C# 做题记录&#xff0c;方便自己学习的同时分享出来。 关于编译环境 注意&#xff0c;笔者使用的编译环境是 .NET …

Java学习星球,Java学习路线

目录一、Java学习路线二、学习计划三、为何会有Java学习星球&#xff1f;四、加入星球后&#xff0c;你可以得到什么&#xff1f;五、如何加入Java学习星球&#xff1f;六、打卡挑战大家好&#xff0c;我是哪吒&#xff0c;一个靠着热情攀登至C站巅峰的中年男子&#xff0c;CSD…

全网最火爆,Python接口自动化测试-接口数据 RSA 加密和签名实现(超详细)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 在工作中&#xff0…

算法基础---数学知识

文章目录 质数 试除法判定质数试除法分解质因数朴素筛法求质数埃氏筛法求质数线性筛法求质数约数 试除法求所有约数试除法求所有约数之和约数个数和约数之和欧几里得算法一、质数 1.试除法判定质数--O(sqrt(N)) 原理&#xff1a;把从[2,n-1]中的每一个自然数作为除数来除n&a…

基于 Apache Flink 的实时计算数据流业务引擎在京东零售的实践和落地

摘要&#xff1a;本文整理自京东零售-技术研发与数据中心张颖&闫莉刚在 ApacheCon Asia 2022 的分享。内容主要包括五个方面&#xff1a; 京东零售实时计算的现状实时计算框架场景优化&#xff1a;TopN场景优化&#xff1a;动线分析场景优化&#xff1a;FLINK 一站式机器学…

【Linux】写一个基础的bash

头文件#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h> #include<sys/stat.h> #include<string.h> #include<pwd.h> #include<dirent.h>分割输入的命令串字符串或参数内容为空则退出strtok( ,…