Qt QGraphics导入背景图并绘制图形,画布移动、缩放、图形旋转等

news2024/11/24 3:02:28

前言

之前写过一篇博文《Qt鼠标拖动绘制基本几何图形》 ,这是介绍使用QGraphic中利用鼠标事件实现基本几何图形的绘制,支持直线、矩形、圆形、椭圆,本次是在此基础上进行扩展,实现背景图导入,并在图片上进行几何图形绘制,包括矩形、圆形等,支持画布整体移动、放大和缩小,画布恢复,图形item选中、移动、旋转、item移动,会实时显示全局坐标以及相对于背景画布的坐标

本文提供基本功能实现,便于后期在此基础上进行扩展。

先看效果图:
在这里插入图片描述


本文Demo下载


正文

在《Qt鼠标拖动绘制基本几何图形》文中已经介绍了绘制几何图形的基本逻辑,这里就不再赘述。本文扩展的首要内容是导入一张图片后在被禁图上进行绘制,缩放和移动也是跟随整个背景来进行的,所以在导入图片后首先要根据图片的尺寸来创建一个父item

void GsMainScene::createRootItem(const QString &imgPath)
{
    if(m_pRootItem){
        SAFE_DELETE(m_pRootItem)
    }

    auto img = QImage(imgPath);
    auto imgSize = img.size();
    QSizeF newSize;

    if((qreal)imgSize.width()/imgSize.height() > (qreal)sceneRect().width()/sceneRect().height()){
        newSize.setWidth(sceneRect().width());
        newSize.setHeight((qreal)imgSize.height()*sceneRect().width()/imgSize.width());
    }
    else{
        newSize.setHeight(sceneRect().height());
        newSize.setWidth((qreal)imgSize.width()*sceneRect().height()/imgSize.height());
    }

    m_pRootItem = new GsRootItem(newSize);
    connect(m_pRootItem,&GsRootItem::sigPosInfoChanged,this,&GsMainScene::sigPosInfoChanged);
    addItem(m_pRootItem);
    m_pRootItem->moveBy(sceneRect().width()/2-newSize.width()/2.,sceneRect().height()/2.-newSize.height()/2.);
    m_pRootItem->setBackgroudImage(img);
    m_pRootItem->setImgScaleRatio((qreal)newSize.height()/imgSize.height());
    emit sigPosInfoChanged(""); //清空
}

接下来再通过鼠标绘制的几何图形都是以这个rootItem为父类,这样就可以整体进行移动和缩放。

缩放代码:

void GsMainScene::scaleView(GsScaleType type)
{
    auto view = views().first();
    QTransform oldMatrix = view->transform();
    view->resetTransform();
    view->translate(oldMatrix.dx(), oldMatrix.dy());
    if(type == Scale_Zoom_In){
        m_nScaleValue += 5;
    }
    else if(type == Scale_Zoom_Out){
        m_nScaleValue -= 5;
    }
    else if(type == Scale_Reset){
        m_nScaleValue = 100;
    }
    view->scale(m_nScaleValue/100., m_nScaleValue/100.);
}

接下来图形的旋转,鼠标移动到图形的右下角按住鼠标左键旋转鼠标可以实现图形旋转,这个需要在对应的图元中处理鼠标移动事件来实现:

void GsShapeRectangeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
    if(m_bRotate){
        // 设置中心点为原点
        QPointF originPos = this->boundingRect().center();
        // 从原点延伸出去两条线,鼠标按下时的点和当前鼠标位置所在点的连线
        QLineF p1 = QLineF(originPos, m_initPos);
        QLineF p2 = QLineF(originPos, e->pos());
        // 旋转角度
        qreal dRotateAngle = p2.angleTo(p1);

        // 旋转中心
        this->setTransformOriginPoint(originPos);

        // 计算当前旋转的角度
        qreal dCurAngle = this->rotation() + dRotateAngle;
        while (dCurAngle > 360.0) {
            dCurAngle -= 360.0;
        }

        // 设置旋转角度
        this->setRotation(dCurAngle);
        this->update();
    }
    else{
        QGraphicsObject::mouseMoveEvent(e);
    }
}

以上是几个实现的关键代码,绘制图形部分在《Qt鼠标拖动绘制基本几何图形》中已经介绍过。

演示Demo中还包含了绘制直线、椭圆等,旋转图形只在四边形中实现了
在这里插入图片描述
其它图形要实现旋转也是同样的道理。

在之前的文章《Qt 鼠标/触屏绘制平滑曲线,支持矢量/非矢量方式》中还介绍了如何在QGraphic中通过鼠标绘制曲线,可以集成进来支持更多丰富的功能,达到自己想要的效果。

扩展

相关博文
Qt鼠标拖动绘制基本几何图形
Qt 鼠标/触屏绘制平滑曲线,支持矢量/非矢量方式
Qt 实现钢笔画线效果详细原理


本文Demo下载


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

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

相关文章

现货白银行情实时行情与展望

现货白银作为低门槛、高收益的贵金属投资工具,因为交易时间自且没有涨跌幅限制而大受全球投资者追捧,它每天的实时行情走势中充满机会,投资者可结合技术和基本面分析手段,预测其未来的价格走势,在市场的波动中把握住获…

Go编写流量代理工具

目录 这是一个演示主要分为俩包:流程:逻辑:(端口随意,本地ssh为例)用法:文件地址:代码如下: 这是一个演示 代理本地HTTP服务 代理局域网SSH服务 其他的TCP服务没测试了 主要分为俩包&#x…

什么是DevOps? 什么是DORA?

1. 前言 对于搞云原生应用的同学,对于DevOps和DORA应该都不陌生。但对于传统应用程序开发的同学,经常被DevOps, Microservice, CICD, DORA这些新颖的名词搞得晕头转向。那么到底什么是DevOps? 什么是DORA呢? 2. 解析 2.1 DevOps DevOps并…

群晖NAS搭建WebDV服务手机ES文件浏览器远程访问

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址 转载自cpolar极点云文章:群晖NAS搭建WebDAV服务手机ES文件浏览器远程访问 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,我们在群辉中开启WebDav服…

支持刷机(OpenWrt)的路由器大全

2023年上半年最热门的刷机路由器当然是360T7、小米WR30U这两款,主要是性价比高,闲鱼100多搞定,支持刷OpenWrt、支持WiFi6,采用MTK798X系列处理器,性能强,轻松跑满千兆,如果你想追新,…

SpringMVC基础知识

一、SpringMVC 1. Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件…

云捷|打破应用孤岛加速企业数字化转型

CBG云服务BU X 神州数码云基地 一、引言 从流程信息化到整体的数字化转型,对企业而言是一场深刻的升级再造。企业在决心开启数字化转型之路后,有近5成民营企业数字化转型采用标准化工具;关于“贵公司未来将在工作中增加哪些数字应用的使用…

强化学习从基础到进阶-案例与实践[4.2]:深度Q网络DQN-Cart pole游戏展示

【强化学习原理项目专栏】必看系列:单智能体、多智能体算法原理项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍:【强化学习原理项目专栏】必看系列:单智能体、多智能体算法原理项目实战、相关技巧…

基于PaddleDetection fairmot目标跟踪 C++ 部署

1 源码下载 PaddleDetection 2 工程编译 参考:paddle 目标检测C部署流程 3 导出模型 python tools/export_model.py -c configs/mot/fairmot/fairmot_dla34_30e_576x320.yml --output_dir ./inference -o weightshttps://paddledet.bj.bcebos.com/models/mot/…

AutoSAR系列讲解(入门篇)4.7-BSW的Diagnostics功能

一、架构与术语解释 首先简单介绍以下诊断(Diagnostics),由于百度百科中就有很好的解释,这里直接引用一下: 汽车诊断技术是凭借仪器设备对汽车进行性能测试和故障检查的方法和手段,它能够测试出汽车各项工作…

CMU 15-445 -- 存储篇 - 02

CMU 15-445 -- 存储篇 - 02 引言Database StorageDisk Manager 简介计算机存储体系为什么不使用 OS 自带的磁盘管理模块磁盘管理模块的核心问题在文件中表示数据库File StorageDatabase PagesHeap File OrganizationPage LayoutData LayoutTuple LayoutTuple Storage Data Repr…

Windows Update当前无法检查更新怎么办?

当进行Windows更新或升级时,可能会提示“Windows Update当前无法检查更新,因为未运行服务。您可能需要重新启动计算机”。而当重启也无法解决问题时,我们该怎么办呢?下面我们就来了解一下。 1、删除Software Distribution文件夹中…

Hyperledger Fabric交易流程分析

1、交易流程 客户端利用受支持的SDK(Golang、Java、Node、Python)提供的API构建交易提案请求,将交易事务提案打包成为一个正确的格式。交易提案包含如下要素: ①channelID:通道信息。 ②chaincodelD:要调用的链码信息。 ③timestamp:时间戳。 ④sign:客户…

百度智能车竞赛丝绸之路2——手柄控制

百度智能车竞赛丝绸之路1——智能车设计与编程实现控制 百度智能车竞赛丝绸之路2——手柄控制 一、机器人设计 二、实现原理 本教程使用Python的Serial库和Struct二进制数据解析库去实现Xbox手柄百度大脑学习开发板(上位机)和机器人控制器(…

9小时通关 黑马新教程发布,含重磅项目~

随着测试行业的蓬勃发展,对从业者的要求越来越高,自动化测试已经成为软件测试中一个重要组成部分,广泛应用于各行各业。甚至,在圈子中还流传着这样一句话:学好测试自动化,年薪30万不在话下! 今…

Qt读写文件

一、界面 项目文件结构 样例文件 中芯国际近期做出了两个重要改变:第一个是调整财报披露方式,不再公布芯片制程的营收占比,而只公布晶圆尺寸的营收占比;第二个是撤消14nm工艺的官方展示,只有28nm、40nm及以上的芯片工…

LeNet基础

目录 1.LeNet简介 1.1基本介绍 1.2网络结构 2.LetNet在pytorch中的使用 2.1首先定义模型 2.2初始化数据集,初始化模型,同时训练数据。 2.3 训练结果​编辑 2.4绘制曲线 1.LeNet简介 1.1基本介绍 LeNet(LeNet-5)是历史上第…

磁盘阵列(RAID)

什么是磁盘阵列 磁盘阵列(RAID)是一种将多个物理硬盘组合成一个逻辑存储单元的技术。这种技术可以提高数据存储的可靠性、性能或容量,并且可以在某些情况下提供备份和灾难恢复功能。 RAID技术可以通过在多个硬盘之间分配数据来提高性能。例…

事务处理相关

目录 步骤1.创建一个数据表 步骤2:创建项目导入jar包 步骤3:根据表创建模型类 步骤5:创建Service接口和实现类 步骤6:添加jdbc.properties文件 步骤7:创建JdbcConfig配置类 步骤8:创建MybatisConfig配置类 步骤9:创建SpringConfig配置类 步骤10:编写测试类 开启事务 1…

电磁阀原理精髓

一、引用 电磁阀在液/气路系统中,用来实现液路的通断或液流方向的改变,它一般具有一个可以在线圈电磁力驱动下滑动的阀芯,阀芯在不同的位置时,电磁阀的通路也就不同。 阀芯在线圈不通电时处在甲位置,在线圈通电时处在…