Qt(十二)Graphics View 绘图架构(三)

文章目录

      • 一、QGraphicsView相关整理
      • 二、QGraphicsView架构下实时鼠标绘制图形
        • 2.1 鼠标拖拽绘图说明
        • 2.2 记录图形第一个绘制点
        • 2.3 实时获取鼠标最新位置并绘图
        • 2.4 释放绘制点,绘制最终图形
      • 三、QGraphicsView 在鼠标点击处进行放大缩小

一、QGraphicsView相关整理

项目中频繁地使用了QGraphicsView相关的类
(1)继承QGraphicsView,改写下面的protected成员函数进行自定义操作:

protected:void keyPressEvent(QKeyEvent *event);void mousePressEvent(QMouseEvent *event);void paintEvent(QPaintEvent * event);void mouseMoveEvent(QMouseEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);void wheelEvent(QWheelEvent *event);

使用中注意,如果想使QGraphicsView中已定义的操作任然有效,则需要在函数定义代码中添加下列语句, 以便实现父类已经是实现的默认操作。

QGraphicsView::keyPressEvent(event);
QGraphicsView::mousePressEvent(event);
QGraphicsView::mouseMoveEvent(event);
QGraphicsView::paintEvent(event);
QGraphicsView::mouseDoubleClickEvent(event);
QGraphicsView::wheelEvent(event);

(2) 可创建QGraphicsScene对象添加到QGraphicsView对象中(setScene(QgraphicsScene* scene)),可以使用同样的方法继承QGraphicsScene进行自定义操作;

(3) QGraphicsView中有**horizontalScrollBar()verticalScrollBar()**可以返回视图中的滚动条,下面的代码可以设置滚动条的显示模式

m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);// 设置在视图中进行拖动
setDragMode(QGraphicsView::ScrollHandDrag);

(4)当使用自定义的右键选择菜单时,需要下面的语句,在槽函数on_graphicsView_customContextMenuRequested(QPoint) 中定义相关操作

m_graphicsView->setContextMenuPolicy (Qt::CustomContextMenu);connect(m_graphicsView,SIGNAL(customContextMenuRequested(QPoint)),this, SLOT(on_graphicsView_customContextMenuRequested(QPoint)));

(5)QGraphicsItem相关:
QGraphicsTextItem, QGraphicsLineItem, QGraphicsRectItem 三个Graphicsitem

QGraphicsTextItem *title = new QGraphicsTextItem();
title->setPlainText(name);
title->setPos(10, 10);
title->setFont(QFont(QString::fromLocal8Bit ("楷体"),15));
title->setDefaultTextColor(QColor(160, 160, 160));
title->setZValue(30);//设置图层QGraphicsLineItem *linetemp = new QGraphicsLineItem();
QPen pen = linetemp->pen();
pen.setColor(QColor(81, 82, 84));
pen.setWidth(4);
linetemp->setPen(pen);
linetemp->setLine(QLineF(0, 0, 10,  10));
linetemp->setZValue (12);QGraphicsRectItem* m_overAreaTop = new QGraphicsRectItem();
m_overAreaTop->setRect(0,0,10,10);
m_overAreaTop->setBrush(QBrush(QColor(64, 66, 68)));//填充色
m_overAreaTop->setPen(QPen(QColor(64, 66, 68)));//边框线
m_overAreaTop->setZValue(10);

每个item设置ZValue可以在对象重合时选择显示哪个对象显示在最前面。
可以通过boundingRect()获取item的边界框QRect类对象,并可以通过mapFromGlobal、mapRectToParent、mapRectToScene等进行坐标转换,最后通过QRect的contains()判断相关点的包含问题。

二、QGraphicsView架构下实时鼠标绘制图形

2.1 鼠标拖拽绘图说明

想要实现鼠标拖拽绘图的效果,离不开鼠标的三大事件:按下移动释放

绘制矩形框的核心流程
第一步:鼠标左键点击,记录初始点击位置
第二步:在窗口中移动鼠标,实时获取鼠标拖动点,根据拖动点绘制指定形状
第三步:鼠标点击右键释放鼠标,绘制最终图形

在进行鼠标点击绘制的时候,为了兼容多个图形的实时绘制,这里,不只是用两个QPoint成员变量记录鼠标点,而是采取了vector<QPontF>容器存储的方式。
例如:三角形图形,需要三个点才能确定图形;曲线图形,是由N多个点才能确定图形;等等…

图形枚举类型 枚举类型 形状
Drawing_Normal无图形绘制
Drawing_Circular 圆形
Drawing_StraightLine 直线
Drawing_Rectangular 矩形
Drawing_Triangle 三角形
Drawing_ManyLineSegements多线段
Drawing_Curve 曲线
2.2 记录图形第一个绘制点

这里以Drawing_Rectangular为例
鼠标点击后才能获取当前点击点的位置,记录按下点操作应该是在鼠标的mousePressEvent中实现的

void QCustomQGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * e)
{//TODO:鼠标左键,点击绘制图形;鼠标右键,点击拖动图形QGraphicsScene::mousePressEvent(e);if (e->button() & Qt::LeftButton){//当图形处于绘制状态时, 记录鼠标按下的点if (m_enumShape!= Drawing_Normal) m_vetPoints.push_back(e->scenePos());}
}
2.3 实时获取鼠标最新位置并绘图

鼠标想要实时绘制,在移动鼠标的mouseMoveEvent事件中操作的。

void QCustomQGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * e)
{//TODO:鼠标移动时,如果存在有效图形类型,进行图形绘制QGraphicsScene::mouseMoveEvent(e);if (m_enumShape!= Drawing_Normal){m_pTempLayer->DrawShape(m_enumShape, m_vetPt, e->scenePos());}
}

DrawShape函数 的讲解

  • 参数1:图形的枚举类型,根据不同枚举,绘制不同的图形
  • 参数2:vector<QPointF>传入已经记录的鼠标点,可以是多个,但最少是1个。就例如当前绘制矩形来说,该容器中只是存储了一个绘制点。
  • 参数3:鼠标在mouseMoveEvent中实时拖动点
    DrawShape函数实现代码,如下:
void QTempCanvasLayer::DrawShape(ENUM_DrawingGraphic enumShape, std::vector<QPointF> vetPt, QPointF ptCurrent)
{m_pTempCanvasImg->fill(Qt::transparent);  //避免拖动鼠标绘制图形时,线条重叠m_pTempPainter->setRenderHint(QPainter::Antialiasing, true);m_pTempPainter->setCompositionMode(QPainter::CompositionMode_Source);m_pTempPainter->setPen(QPen(QColor(51, 51, 51), 1, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin));switch (enumShape){case Drawing_Circular:          //圆形break;case Drawing_StraightLine:      //直线break;case Drawing_Rectangular:       //矩形m_pTempPainter->drawRect(QRectF(vetPt[0], ptCurrent));break;case Drawing_Triangle:          //三角形break;case Drawing_ManyLineSegements: //多线段break;case Drawing_Curve:             //曲线break;default:break;}update();
}
2.4 释放绘制点,绘制最终图形

鼠标事件:mouseReleaseEvent 绘制鼠标

void QCustomQGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * e)
{//TODO:鼠标释放之后操作QGraphicsScene::mouseReleaseEvent(e);if (m_enumShape == Drawing_Normal) return;//存在有效的图形类型,进行最终图形绘制if (e->button() & Qt::RightButton){if (m_enumShape == Drawing_Rectangular){//绘制直线,需要存储两个有效点if (m_vetPt.size() == 2){this->DrawRealShape(m_vetPt);this->ClearCurrentDrawingShape();   //如果当前正在绘制图形,直接清除}}}
}

三、QGraphicsView 在鼠标点击处进行放大缩小

使用QGraphicsView类的设置属性函数.在构造函数中增加下面两个函数即可。

ui->View_ImageOpro->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
ui->View_ImageOpro->setResizeAnchor(QGraphicsView::AnchorUnderMouse);

setDragMode枚举值:

  • QGraphicsView::NoDrag,
  • QGraphicsView::RubberBandDrag
  • QGraphicsView::ScrollHandDrag
MyGraphicsView::MyGraphicsView()
{//设置ui控件属性setDragMode(QGraphicsView::NoDrag);scale_m = 1;                                //图形原始比例setStyleSheet("padding: 0px; border: 0px;");//无边框setMouseTracking(true);                    //跟踪鼠标位置setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);  //隐藏水平条setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);    //隐藏竖条setTransformationAnchor(QGraphicsView::AnchorUnderMouse);setResizeAnchor(QGraphicsView::AnchorUnderMouse);}
void MyGraphicsView::wheelEvent ( QWheelEvent * event )
{if (event->modifiers() == Qt::CTRL){                  //按住ctrl键 可以放大缩小if((event->delta() > 0)&&(scale_m >= 50)) return; //最大放大到原始图像的50倍// 图像缩小到自适应大小之后就不继续缩小; 重置图片大小和位置,使之自适应控件窗口大小else if((event->delta() < 0)&&(scale_m <= 0.01)) return;else{// 当前放缩倍数;qreal scaleFactor = this->matrix().m11();scale_m = scaleFactor;int wheelDeltaValue = event->delta();if (wheelDeltaValue > 0) this->scale(1.2, 1.2); // 向上滚动,放大;else this->scale(1.0 / 1.2, 1.0 / 1.2);         // 向下滚动,缩小;update();}}    
}

QPainter鼠标绘制矩形,多边形:https://blog.csdn.net/Stone_OverLooking/article/details/112886734

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14 Php学习:表单

表单 PHP 表单是用于收集用户输入的工具&#xff0c;通常用于网站开发。PHP 可以与 HTML 表单一起使用&#xff0c;用于处理用户提交的数据。通过 PHP 表单&#xff0c;您可以创建各种类型的表单&#xff0c;包括文本输入框、复选框、下拉菜单等&#xff0c;以便用户可以填写和…

主存储器与CPU之间的连接(会画图)

位扩展 字扩展 由于只有A13&#xff0c; A14 连到了译码器上&#xff0c;以、因此该译码器是一个 2/4 译码器&#xff0c;对应的选片有四种。选中第一个选片&#xff0c;就是把译码器“0口置0&#xff0c; 1~3口置1”&#xff0c;因为CS有非号&#xff0c;因此&#xff0c;低电…

【C++】string的使用

目录 1、为什么学习string类&#xff1f; 2、标准库中的string类 2.1 string类 2.2 string类的常见接口声明 2.2.1 string类的常见构造 ​编辑 2.2.2 string类对象的访问及遍历操作 2.2.3 string类对象的容量操作 2.2.4 string类对象的修改操作 ​编辑 1、为什么学习s…

excel中vlookup查找值必须在table_array的第一列,有其他办法吗有XLOOKUP

vlookup查找值必须在table_array的第一列&#xff0c;有其他办法吗&#xff1f;有XLOOKUP。 vlookup 查找如下&#xff0c;查找值必须在table_array的第一列 如果下面&#xff0c;编码和名称交换位置&#xff0c;就不能使用vlookup查找了。 XLOOKUP 查找如下

Linux:进程调度

Linux&#xff1a;进程调度 进程优先级查看优先级调整优先级 Linux 2.6 内核进程调度队列 进程优先级 查看优先级 在Linux中&#xff0c;进程是有优先级的&#xff0c;我们可以通过指令ps -la来查看&#xff1a; 其中PRI表示priority优先级&#xff0c;在Linux中&#xff0c;…

解决 vue install 引发的 failed Error: not found: python2 问题

发生 install 异常时&#xff0c;提示信息如下所示&#xff1a; npm ERR! code 1 npm ERR! path U:\cnblogs\fanfengping-dtops\fanfengping-dtops-front\node_modules\node-sass npm ERR! command failed npm ERR! command U:\Windows\system32\cmd.exe /d /s /c node scripts…

基于Matlab机器人工具箱对Dobot机械臂的研究

文章目录 文章目录 前言 一、Dobot Mangician 分析 二、Matlab 机器人工具箱 1. 建立模型 2. DoBot 正向运动学 3. Dobot 逆运动学 4. Dobot workpace 5. Dobot轨迹规划 三、Dobot studio 1. DoBot teaching 2. DoBot Python 程序 总结 前言 在本实验中&#xf…

智能边缘计算采集网关助您远程调试SINAMICS S200伺服-天拓四方

您还在为每次调试都要去现场而烦恼吗&#xff1f;智能边缘计算采集网关助您远程调试SINAMICS S200伺服&#xff0c;让您足不出户&#xff0c;就能“运筹帷幄之中&#xff0c;决胜千里之外”。 新品介绍 SINAMICS S200 PN是西门子推出的新一代伺服驱动系统&#xff0c;采用Mot…

upload-labs第十一十二关

第十一关 $is_upload false; $msg null; if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_ext substr($_FILES[upload_file][name],strrpos($_FILES[upload_file][name],".")1);if(in_array($file_ext,$ext_arr)){$temp_file $_FILES[upload_fil…

博客文章:AWS re:Invent 2023 新产品深度解析 - 第四部分

TOC &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能&#xff0c;共同成长&#xff01; 写在最前面 去年发布文章的一部分&#xff0c;由于内…

【5】DongshanPI-Seven 应用开发_网络编程TCPUDP

目录 1、网络编程概念2、网络编程的API2.1 网络通信交互示意图2.2 主要API 3、编程测试3.1 TCP 测试3.1.1 server 程序3.1.2 Client 程序3.1.3 测试结果 3.2 UDP 测试3.2.1 udp server3.2.2 udp client3.2.3 测试结果 1、网络编程概念 1.数据传输三要素&#xff1a;源、目的、…

网络的坚实与灵活:工业与常规以太网交换机的差异解析

&#x1f310;&#x1f310;在当今互联网和物联网迅速发展的背景下&#xff0c;以太网交换机作为网络通信的核心设备&#xff0c;其性能和稳定性对于整个网络系统的运行至关重要。工业以太网交换机和常规以太网交换机乍一看似乎很相似&#xff0c;但两者之间存在着一些关键区别…

深入探索:Zookeeper+消息队列(kafka)集群

目录 前言 一、Zookeeper概述 1、Zookeeper概念 2、Zookeeper 特点 3、Zookeeper工作机制 4、Zookeeper 选举机制 4.1 第一次启动选举机制 4.2 非第一次启动选举机制 5、Zookeeper 数据结构 6、Zookeeper 应用场景 二、部署 Zookeeper 集群 1、环境部署 2、安装 z…

OpenHarmony音频和音乐编码格式—vorbis

简介 一种通用音频和音乐编码格式。 Vorbis编解码器规范属于公共领域。所有技术细节都已发布并记录&#xff0c;任何软件实体都可以充分利用该格式&#xff0c;而无需支付许可费、版税或专利问题。 下载安装 直接在OpenHarmony-SIG仓中搜索vorbis并下载。 使用说明 以OpenHa…

测试JAVA 测开

测试、java测开 1、测试用例要素&#xff08;4个重要要素&#xff09;2、测试用例的好处3、测试用例的设计方法3.1 基于需求设计测试用例3.2 等价类3.3 边界值3.4 判定表 1、测试用例要素&#xff08;4个重要要素&#xff09; 测试环境操作步骤测试数据预期结果 2、测试用例的…

企业数字化与数智化的区别是什么?

一、引言 随着信息技术的迅猛发展和应用普及&#xff0c;企业面临着数字化与数智化两大转型趋势。数字化主要关注数据的收集、整合和流程优化&#xff0c;而数智化则在此基础上进一步引入智能技术&#xff0c;实现业务的自动化、智能化和决策的科学化。探讨企业数字化与数智化…

初级C语言:6 结构体

6.1 结构体的声明 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 内置类型&#xff1a;char&#xff1b;short&#xff1b;int&#xff1b;long&#xff1b;long long&#xff1b;float&#xff1b;double 复杂对象的描述就会使…

通过拖拽动态调整div的大小

最近遇到一个需求&#xff0c;页面展示两块内容&#xff0c;需要通过拖拽可以动态改变大小&#xff0c;如下图&#xff1a; 实现思路&#xff1a;其实就是改变div样式的width&#xff0c;本质上就是Dom操作。 完整代码&#xff1a;&#xff08;基于vue2项目实践&#xff09; …

第 7 章 导航实现(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 准备工作 请先安装相关的ROS功能包&#xff1a; 安装 gmapping 包(用于构建地图)&#xff1a; sudo apt inst…

爬虫机试题-爬取新闻网站

之前投简历时遇到了这样的一个笔试。本以为会是数据结构算法之类的没想到直接发了一个word直接提需求&#xff0c;感觉挺有意思就写了这篇文章&#xff0c;感兴趣的朋友可以看看。 拿到urllist 通过分析页面结构我们得以知道&#xff0c;这个页面本身没有新闻信息&#xff0c;是…