当前位置: 首页 > news >正文

Qt 2D绘图之五:图形视图框架的结构、坐标系统和框架间的事件处理与传播

参考文章链接:
Qt 2D绘图之五:图形视图框架的结构和坐标系统
Qt 2D绘图之六:图形视图框架的事件处理与传播

图形视图框架的结构

在前面讲的基本绘图中,我们可以自己绘制各种图形,并且控制它们。但是,如果需要同时绘制很多个相同或不同的图形,并且要控制它们的移动、检测它们的碰撞和叠加;或者我们想让自己绘制的图形可以拖动位置、进行缩放和旋转等操作。实现这些功能,要是还使用以前的方法,那么会十分困难。解决这些问题,可以使用Qt提供的图形视图框架。

图形视图(Graphics View)框架结构的主要特点如下:

  • 图形视图(Graphics View)可以对大量定制的2D图形项进行管理和相互作用。视图部件可以让所有图形项可视化,它还提供了缩放和旋转功能
  • 框架中包含了一个事件传播构架,提供了和场景中的图形项进行精确的双精度交互的能力,图形项可以处理键盘事件,鼠标的按下、移动、释放和双击事件,还可以跟踪鼠标的移动
  • 图形视图框架使用一个BSP(Binary Space Partitioning)树来快速发现图形项,也正是因为如此,它可以实时显示一个巨大的场景,甚至包含上百万个图形项
    图形视图框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。

图形视图结构主要包含三部分:

  • 场景(Scene) :QGraphicsScene类
  • 视图(View) :QGraphicsView类
  • 图形项(Item):QGraphicsItem类

场景(Scene)

场景是图形项QGraphicsItem对象的容器,其主要完成的工作包括:
(1)提供用于管理大量图形项的快速接口
(2)传播事件给每一个图形项
(3)管理图形项的状态(如选择和焦点处理);
(4)提供无变换的渲染功能,主要用于打印

下面是一些QGraphicsScene的常用函数

  • 可以调用QGraphicsScene: :addItem()函数将图形项添加到场景中,然后调用任意一个图形项发现函数来检索添加的图形项。
  • QGraphicsScene::items()函数和其他几个重载函数可以返回符合条件的所有图形项。这些图形项不是与指定的点、矩形、多边形或者矢量路径相交,就是包含在它们之中。
  • QGraphicsScene::itemAt()函数返回指定点的最上面的图形项。所有的图形项发现函数返回的图形项都是使用递减顺序(例如第一个返回的图形项在最上面,最后返回的图形项在最下面)。
  • 如果要从场景中删除一个图形项,可以使用QGraphicsScene::Removeltem()函数。
  • 可以通过向QGraphicsScene::setSelectionArea()函数中传递一个任意的形状来选择场景中指定的图形项。
  • 如果要获取当前选取的所有图形项的列表,可以使用QGraphicsScene:: selectedltems()函数。
  • 另外可以调用QGraphicsScene:: setFocusItem()或者 QGraph­icsScene:: setFocus( )函数来为一个图形项设置焦点,调用QGraphicsScene:: focusItem()函数来获取当前获得焦点的图形项。
  • QGraphicsScene:: render()函数将场景中的一部分渲染到一个绘图设备上。

下面先来看一个最简单的例子。新建空的Qt项目(Empty qmake Project),项目名称为myscene。然后在这个项目中添加新的C++源文件,命名为main.cpp。添加完成后首先在myscene.pro文件中添加一行代码:

QT += widgets

然后将main.cpp的内容更改如下。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QDebug>int main(int argc,char* argv[ ])
{QApplication app(argc,argv);//新建场景QGraphicsScene scene;//创建矩形图形项QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100);//将图形项添加到场景中scene.addItem(item);//输出(50, 50)点处的图形项qDebug() << scene.itemAt(50,50,QTransform());return app.exec();
}

这里先创建了一个场景,然后创建了一个矩形图形项,并且将该图形项添加到了场景中。然后使用itemAt()函数来返回指定坐标处最顶层的图形项,这里返回的就是刚才添加的矩形图形项。现在可以运行程序,不过因为还没有设置视图,所以不会出现任何图形界面,这时可以在应用程序输出栏中看到输出的项目的信息如下:

QGraphicsItem(0x161015c8, pos=0,0)

视图(View)

QGraphicsView提供了视图部件,它用来使场景中的内容可视化可以连接多个视图到同一个场景来为相同的数据集提供多个视口

下面是一些QGraphicsView:的常用函数

  • 视图部件是一个可滚动的区域,提供了一个滚动条来浏览大的场景,可以使用setDragMode()函数以QGraphicsView::SCrollHandDrag为参数来使光标变为手掌形状,从而可以拖动场景。
  • 如果设置 setDragMode()的参数为QGraphicsView::RubberBandDrag,那么可以在视图上使用 鼠标拖出橡皮筋框来选择图形项。
  • 默认的QGraphicsView提供了一个QWidget作为视口部件,如果要使用OpenGL进行植染,可以调用QGraphicsView::setViewport()设置QOpenGLWidget作为视口。QGraphicsView会获取视口部件的拥有权(ownership)。

在前面的程序中先添加头文件# include ,然后在主函数中 “return app. exec();”一行代码前继续添加如下代码:

//为场景创建视图
QGraphicsView view(&scene);
//设置场景的前景色
view.setForegroundBrush(QColor(255, 255, 0, 100));
//设置场景的背景图片
view.setBackgroundBrush(QPixmap("../myScene/background.png"));
view.resize(400, 300);
view.show();

这里新建了视图部件,并指定了要可视化的场景。然后为该视图设置了场景前景色和背景图片。**一个场景分为3层:图形项层(ItemLayer)、前景层(ForegroundLayer)和背景层(BackgroundLayer)。场景的绘制总是从背景层开始,然后是图形项层,最后是前景层。前景层和背景层都可以使用QBrush进行填充,比如使用渐变和贴图等。**这里的前景色设置为半透明的黄色,当然也可以设置为其他的填充。这里要提示一下,其实使用好前景色可以实现很多特殊的效果,比如使用半透明的黑色便可以实现夜幕降临的效果。

代码中使用了 QGraphicsView类中的函数来设置场景中的背景和前景,其实也可以使用QGraphicsScene中的同名函数来实现,不过它们的效果并不完全 一样。如果使用QGraphicsScene对象设置了场景背景或者前景,那么对所有关联了该场景的视图都有效,而QGraphicsView对象设置的场景的背景或者前景,只对它本身对应的视图有效。

运行程序,效果如下图所示。可以看到矩形图形项和背景图片都是在视图中间部分进行绘制的,这个问题会在后面的坐标系统部分详细讲解。
在这里插入图片描述

图形项

QGraphicsItem是场景中图形项的基类。图形视图框架为典型的形状提供了标准的图形项,比如矩形(QGraphicsRectlem)、椭圆(QGraphicsEllipseltem)和文本项(QGraphicsTextltem)。不过,只有编写自定义的图形项时才能发挥QGraphicsItem的强大功能。
QGraphicsItem主要支持以下功能:

  • 鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件;
  • 键盘输入焦点和键盘事件;
  • 拖放事件;
  • 分组,使用QGraphicsItemGroup通过parent-child关系来实现

相关文章:

Qt 2D绘图之五:图形视图框架的结构、坐标系统和框架间的事件处理与传播

参考文章链接: Qt 2D绘图之五:图形视图框架的结构和坐标系统 Qt 2D绘图之六:图形视图框架的事件处理与传播 图形视图框架的结构 在前面讲的基本绘图中,我们可以自己绘制各种图形,并且控制它们。但是,如果需要同时绘制很多个相同或不同的图形,并且要控制它们的移动、…...

基于SpringBoot+Vue的美妆购物网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

MySQL之创建和管理表

目录 1. MySQL中的数据类型​编辑​编辑 2. 创建和管理数据库 方式1&#xff1a;创建数据库 方式2&#xff1a;创建数据库并指定字符集 方式3&#xff1a;判断数据库是否已经存在&#xff0c;不存在则创建数据库&#xff08; 推荐 &#xff09; 总结 2.2 使用数据库 查看当…...

肌肉骨骼肿瘤治疗市场:潜力无限,未来可期

肌肉骨骼肿瘤治疗作为现代医学的重要分支&#xff0c;专注于应对骨骼和肌肉系统中的良性和恶性肿瘤。随着全球人口老龄化和生活方式的改变&#xff0c;肌肉骨骼疾病日益成为公共卫生的重要问题。与此同时&#xff0c;医疗技术的进步和患者对高质量医疗服务的需求不断推动该市场…...

QGIS 创建三维渲染动画

打开数据包中的denali工程文档&#xff0c;可以看到DEM图层和山体阴影图层。首先创建彩色的山体阴影效果&#xff1a; 接下来新建3D视图&#xff1a; 配置三维地图 配置后&#xff0c;可用鼠标中键、右侧的操作盘等进行三维旋转等操作。 接下来在三维地图中创建动画效果&#x…...

Vue生成类似于打卡页面

数据表格 <el-table :data"tableData" border height"calc(100vh - 240px)" :cell-style"cellFun"><el-table-column label"姓名" show-overflow-tooltip prop"name" align"center"/><el-table-co…...

软件工程——期末复习(2)

Part1&#xff1a;软件工程基本概念 软件程序文档数据 在软件工程中&#xff0c;软件通常被定为程序、文档和数据的集合。程序是按事先设计的功能和性能要求编写的指令序列&#xff1b;程序是完成指定功能的一段特定语言代码。文档是描述程序操作和使用的文档&#xff0c;是与…...

vxe-table 键盘操作,设置按键编辑方式,支持覆盖方式与追加方式

vxe-table 全键盘操作&#xff0c;按键编辑方式设置&#xff0c;覆盖方式与追加方式&#xff1b; 通过 keyboard-config.editMode 设置按键编辑方式&#xff1b;支持覆盖方式编辑和追加方式编辑 安装 npm install vxe-pc-ui4.3.15 vxe-table4.9.15// ... import VxeUI from v…...

【BUG】VMware|vmrest正在运行此虚拟机,无法配置或删除快照

VMware版本&#xff1a;VMware 16 文章目录 省流版问题解决方案 详细解释版问题解决方案总结 省流版 问题 只读&#xff0c;因为vmrest正在运行虚拟机。 解决方案 参考&#xff1a;虚拟机设置&#xff0c;只读&#xff0c;因为vmrest正在运行此虚拟机。有谁遇到过这种问题吗&…...

STM32 串口和I2C结合案例:

需求 1. 电脑通过串口 给单机 下发点灯计划 例如 13322 单片机上的灯 LED1 亮1秒 灭1秒 LED3 亮1秒 灭1秒 LED3 亮一秒 灭1秒 133221332213322-> mian.c #include "usart1.h" #include "M24C02.h" #include "stdio.h" #include "le…...

QT6_UI设计——设置表格

环境&#xff1a;qt6.8 1、放置 双击 2行 、列 设置 3、设置表格内容 读取表格内容 uint16 get_table_value_16_cmd(int row,int column) {if(column<1)return 0;QTableWidgetItem *itemnew QTableWidgetItem;itemui1->tableWidget_2->item(row,column);if(item! nul…...

游戏使用辅助工具修改器检测不到游戏进程应该如何解决?多种解决方法分享

当您在使用游戏辅助工具或修改器时遇到“未检测到游戏进程”的提示&#xff0c;这通常意味着修改器未能正确识别并连接到游戏的运行实例。以下是一些可能的解决方案&#xff1a; 1. 确保游戏已启动&#xff1a;•确认游戏已经完全启动并且正在运行中。有时游戏可能还在加载界面…...

Java JVM(内存结构,垃圾回收,类加载,内存模型)

一、JVM 主要功能 1. 什么是 jvm&#xff1f; JVM&#xff08;Java Virtual Machine)&#xff1a;负责运行 Java 程序的核心组件。它将 Java 字节码&#xff08;.class 文件&#xff09;解释或编译为机器代码&#xff0c;并提供内存管理、垃圾回收和线程管理等功能。 JRE (J…...

C++设计模式(桥接、享元、外观、状态)

一、桥接模式 1.定义 将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。 桥接模式通过使用组合关系而不是继承关系来实现解耦&#xff0c;从而提高系统的灵活性和可扩展性。 2.组成 抽象&#xff1a;定义抽象部分的接口&#xff0c;包含一个指向实现类的对象…...

鸿蒙 DevEco Studio 设置状态栏,调用setWindowSystemBarProperties不生效

参考文章&#xff1a;设置状态栏&#xff0c;调用setWindowSystemBarProperties不生效 我使用 setWindowSystemBarProperties 设置状态栏&#xff0c;不生效。 import window from ohos.window;export default {data: {title: World},setSystemBar() {var windowClass null;…...

Spring03——基于xml的Spring应用

Spring开发中主要对Bean的配置 Bean的常用配置一览如下&#xff1a; Xml配置方式功能描述<bean id"" class"">Bean的id和全限定名配置<bean name"">通过name设置Bean的别名&#xff0c;通过别名也能直接获取到Bean实例<bean sc…...

【AIGC半月报】AIGC大模型启元:2024.12(上)

【AIGC半月报】AIGC大模型启元&#xff1a;2024.12&#xff08;上&#xff09; &#xff08;1&#xff09;OpenAI-12日发布会&#xff08;持续更新中........&#xff09;Day01-12.06&#xff1a;SoraDay02-12.07&#xff1a;ChatGPT圣诞老人风格的语音Day03-12.08&#xff1a;…...

本etcd系列文章补充说明

最开始今年四月份读的是etcdv3.6的main分支的代码&#xff0c;最开始没注意&#xff0c;main分支代码是不断修改的&#xff0c;并且最开始对etcd不太了解&#xff0c;所以源码笔记有些理解不太准确&#xff0c;也可能略有错误&#xff0c;所以年底就回过头来重新复习一遍&#…...

【新品发布】ESP32-P4开发板 —— 启明智显匠心之作,为物联网及HMI产品注入强劲动力

核心亮点&#xff1a; ESP32-P4开发板&#xff0c;是启明智显精心打造的一款高性能物联网开发板。它专为物联网项目及HMI&#xff08;人机界面&#xff09;产品而设计&#xff0c;旨在为您提供卓越的性能和稳定可靠的运行体验。 强大硬件配置&#xff1a; 双核400MHz RISC-V处…...

HTML 添加 文本水印

body,html {margin: 0;height: 100vh;width: 100vw;} // 自定义文案const setting {text: "水印文案", // 水印内容innerDate: true, // 在水印下方增加日期width: 110, // 水印宽度};// 自定义文字水印const watermark (function () {return {build: function (a…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...