在控件graphicsView中实现绘图功能(二)

news2024/11/28 16:36:05

目录

  • 前言:
  • 基础夯实:
    • 1.创建 QGraphicsScene 和 QGraphicsView
    • 2. 在 QGraphicsScene 中添加椭圆
    • 3. 渲染和显示
    • 4. 推荐学习本文之前查看的链接:
  • 效果展示:
  • 实现功能:
  • 遇到问题:
  • 核心代码:
  • 仓库源码:

前言:

对于上一节没有完成的功能进行续写,对ui界面进行简单的修改,添加了椭圆绘制,绘制图形保存在graphicsView中这两个功能,后续会对文字添加,清屏以及图片旋转功能进行添加。

基础夯实:

1.创建 QGraphicsScene 和 QGraphicsView

在你的主窗口或者相应的QWidget中,创建一个 QGraphicsScene 和一个 QGraphicsView。QGraphicsScene 是图形的容器,而 QGraphicsView 用于显示这个场景。

#include <QGraphicsScene>  
#include <QGraphicsView>  
#include <QGraphicsEllipseItem>  
QGraphicsScene *scene = new QGraphicsScene(this);  
QGraphicsView *view = new QGraphicsView(scene, this);  
setCentralWidget(view); // 假设你在一个QMainWindow中

2. 在 QGraphicsScene 中添加椭圆

使用 QGraphicsEllipseItem 创建一个椭圆,并将其添加到 QGraphicsScene 中。你可以指定椭圆的矩形边界(使用 QRectF),或者简单地使用 x, y, width, height 参数。

QGraphicsEllipseItem *ellipse = scene->addEllipse(QRectF(10, 10, 100, 50), QPen(Qt::black), QBrush(Qt::blue));  
// 或者  
// QGraphicsEllipseItem *ellipse = scene->addEllipse(10, 10, 100, 50);  
// 然后你可以设置它的笔和刷  
// ellipse->setPen(QPen(Qt::black));  
// ellipse->setBrush(QBrush(Qt::blue));

3. 渲染和显示

将 QGraphicsView 添加到你的窗口或布局中后,它就会自动显示 QGraphicsScene 中的所有图形项,包括你刚刚添加的椭圆。

4. 推荐学习本文之前查看的链接:

在控件graphicsView中实现绘图功能(一)

效果展示:

在这里插入图片描述

实现功能:

实现了添加了椭圆绘制,绘制图形保存的graphicsView中这两个功能。

遇到问题:

一种图形只能添加一次,不能连续添加。图片无法保存到视图中。

核心代码:

//CustomGraphicsView.cpp
#include "CustomGraphicsView.h"
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QMouseEvent>

CustomGraphicsView::CustomGraphicsView(QWidget *parent)
    : QGraphicsView(parent)
{
}

void CustomGraphicsView::setDrawMode(DrawMode mode)
{
    currentDrawMode = mode;
}

// 辅助函数,用于创建新的椭圆项
QGraphicsEllipseItem* CustomGraphicsView::createEllipseItem(const QRectF &rect, const QPen &pen, const QBrush &brush)
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
    item->setPen(pen);
    item->setBrush(brush);
    scene()->addItem(item);
    ellipseItems.append(item);
    return item;
}


void CustomGraphicsView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        isDrawing = true;
        startPoint = mapToScene(event->pos());

        switch (currentDrawMode) {
        case RectMode:
            // 矩形模式下,初始化矩形的两个角(实际上是同一个点,稍后在move事件中更新)
            rectItem = new QGraphicsRectItem(QRectF(startPoint, QSizeF(0, 0)));
            rectItem->setPen(QPen(Qt::blue)); // 示例颜色
            scene()->addItem(rectItem);
            break;

        case LineMode:
            // 线条模式下,不立即绘制线条,只在move事件中根据起点和当前点绘制
            lineItem = nullptr; // 如果之前有线条,则忽略它(或根据需要重置)
            break;

        case EllipseMode:
            if (!ellipseItem) {
                QRectF ellipseRect(startPoint, QSizeF(0, 0)); // 初始大小为0,稍后在move事件中更新
                ellipseItem = createEllipseItem(ellipseRect, QPen(Qt::green), QBrush(Qt::NoBrush));
            }
            // 否则,不创建新项,只更新startPoint
            break;

        default:
            // ...
            break;
        }

        emit mouseClicked(event->pos());
    }

    QGraphicsView::mousePressEvent(event);
}

void CustomGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (isDrawing) {
        QPointF endPoint = mapToScene(event->pos());

        switch (currentDrawMode) {
        case RectMode:
        {
            QPointF topLeft = QPointF(qMin(startPoint.x(), endPoint.x()), qMin(startPoint.y(), endPoint.y()));
            QPointF bottomRight = QPointF(qMax(startPoint.x(), endPoint.x()), qMax(startPoint.y(), endPoint.y()));
            rectItem->setRect(QRectF(topLeft, bottomRight));
            break;
        }

        case LineMode:
        {
            if (!lineItem) {
                lineItem = scene()->addLine(startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y(), QPen(Qt::red));
            } else {
                lineItem->setLine(QLineF(startPoint, endPoint));
            }
            break;
        }

        case EllipseMode:
        {
            QPointF topLeft = QPointF(qMin(startPoint.x(), endPoint.x()), qMin(startPoint.y(), endPoint.y()));
            QPointF bottomRight = QPointF(qMax(startPoint.x(), endPoint.x()), qMax(startPoint.y(), endPoint.y()));
            QRectF ellipseRect(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y()));
            if (ellipseItem) {
                ellipseItem->setRect(ellipseRect);
            }
            break;
        }

        default:
            // 处理默认情况
            break;
        }
    }
    emit mouseMoved(event->pos());
}

void CustomGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && isDrawing) {
        isDrawing = false;
    }

        emit mouseReleased(event->pos());
        //重置模型项,以便下一次重写
        switch (currentDrawMode) {
        case RectMode:
            rectItem = nullptr;
            break;

        case LineMode:
            lineItem = nullptr;
            break;

        case EllipseMode:
            ellipseItem = nullptr;
            break;
    }

    QGraphicsView::mouseReleaseEvent(event);
}

仓库源码:

代码在之前的链接中进行详细展示了,这里把源码放仓库了,欢迎二次开发:
https://gitee.com/wangning719/drawing

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

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

相关文章

windows环境基于python 实现微信公众号文章推送

材料&#xff1a; 1、python 2.7 或者 python3.x 2、windows 可以通过 “python -m pip --version” 查看当前的pip 版本 E:\Downloads\newsInfo>python -m pip --version pip 20.3.4 from C:\Python27\lib\site-packages\pip (python 2.7) 3、windows 系统 制作&#xf…

基于STM32开发的智能家居安防系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化传感器数据采集与处理安防控制与报警机制Wi-Fi通信与远程监控应用场景 家庭安防系统办公室与商铺的安全监控常见问题及解决方案 常见问题解决方案结论 1. 引言 随着智能家居技术的…

【Hot100】LeetCode—226. 翻转二叉树

目录 1- 思路Queue 队列实现层序遍历 交换左右 2- 实现⭐226. 翻转二叉树——题解思路 3- ACM 实现 原题连接&#xff1a;226. 翻转二叉树 1- 思路 Queue 队列实现层序遍历 交换左右 1- 借助 Queue 实现层序遍历2- 实现左右交换方式 2- 实现 ⭐226. 翻转二叉树——题解思…

带你玩转小程序推广,实现短链接一键跳转

不知道各位有没有想过&#xff0c;短链接直接跳转到微信小程序到底该怎么操作呢&#xff1f;掌握这个小技能&#xff0c;能让你的推广效率大幅提升哦。今天就给大家分享一个全新方法&#xff0c;教你如何从短链接直接跳转到微信小程序&#xff0c;实现高效的一键式跨越。 一、…

源代码怎么进行加密?2024年10款源代码加密软件推荐

在软件开发中&#xff0c;源代码是企业的核心资产&#xff0c;其安全性直接关系到企业的竞争力和商业机密。为了防止源代码被未授权访问、复制或篡改&#xff0c;源代码加密成为了一种常见的安全措施。2024年&#xff0c;随着技术的发展&#xff0c;市场上出现了多种源代码加密…

笔记-系统规划与管理师-案例题-2023年-服务运营管理

【说明】 小李是跨国公司新任命的IT服务经理&#xff0c;帮助提升中国区总部的IT服务管理水平。中国区总部的运维管理体系运营了近三年&#xff0c;内外部环境发生了很多变化&#xff0c;其中: &#xff08;1&#xff09;内部变化包括团队组织结构调整、部分团队精简改为外包支…

纯前端导出excel插件pikaz-excel-js使用小结

最近项目有多个报表开发并前端导出为excel的需求&#xff0c;第一张报表用的是pikaz-excel-js插件&#xff0c;git地址为https://github.com/pikaz-18/pikaz-excel-js&#xff0c;网上文档虽然多&#xff0c;但很多都很基础&#xff0c;官方文档介绍也很简单&#xff0c;没有很…

搜维尔科技:‌Manus VR手套通过触觉反馈技术与机器人进行互动

‌Manus VR手套通过触觉反馈技术与机器人进行互动。‌这种技术允许用户通过手套与机器人进行复杂的动作遥操作和训练&#xff0c;使得用户能够通过手套的动作来控制机器人的运动&#xff0c;同时机器人执行的动作也可以通过手套的触觉反馈功能传达给用户&#xff0c;使用户能够…

线索分析2个要点分析:营销归因与市场ROI转化效果评估

1、营销归因 在复杂的大数据时代&#xff0c;消费者能接触的渠道、设备越来越多&#xff0c;营销活动分析也变得越来越复杂。 在当前的营销环境中&#xff0c;了解并优化营销策略是至关重要的。一个关键的部分是通过分析不同营销活动如何促成商机并赢得订单。而要实现这一目标…

秸秆焚烧自动监测摄像机

秸秆焚烧是一种常见的农业废弃物处理方式&#xff0c;但同时也会产生大量的空气污染物&#xff0c;对环境和人类健康造成威胁。为了监测和控制秸秆焚烧的情况&#xff0c;可以使用秸秆焚烧自动监测摄像机。秸秆焚烧自动监测摄像机 是一种结合了人工智能和机器视觉技术的智能设备…

Linux入门——04 gbd git

gbd命令行调试 默认情况下&#xff0c;GDB无法对现在发布的程序进行调试 debug&#xff08;能调试&#xff09;&&release&#xff08;不能调试&#xff09; linux下GCC或G生成软件默认是release的&#xff01; 1.debug模式 gcc -o mytest mytest.c -g 文件的体积不…

STM32学习记录-04-EXTI外部中断

1 中断系统 &#xff08;1&#xff09;中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续…

在尝试了市面上90%的报表工具后,终于找到了这款免费万能的报表工具!

经常有朋友私信问我有“哪个报表工具好用易上手&#xff1f;”或者是“有哪些适合绝大多数普通职场人的万能报表工具&#xff1f;”等问题。 在这里我总结出大家在报表选择时最在意的三个要点。 一、挑选报表工具的重点 1&#xff09;低门槛上手难度&#xff1a;理想中的报表…

解密《黑神话:悟空》脚本

本文部分参考来自于&#xff1a;john 《黑神话&#xff1a;悟空》这游戏昨天上线了&#xff0c;我第一时间就下载玩了。玩的时候我就挺好奇他们是怎么写的程序&#xff0c;毕竟这么大的游戏项目肯定不会只用C一种语言来写。所以我解压了游戏文件&#xff0c;看看里面有…

开学季必备物品有什么?收下这份高三党开学必备清单!

随着新学期的脚步越来越近&#xff0c;高三的同学们即将迎来人生中至关重要的一年。这一年里&#xff0c;你们将面临无数挑战&#xff0c;同时也将迎来成长的机遇。为了帮助大家更好地准备&#xff0c;我们特别整理了这份“高三党开学必备清单”。这里不仅涵盖了高效学习所需的…

用博达网站群管理平台设计网站时如何引用组件

1 介绍 开发网站时&#xff0c;通常会遇到一种情况&#xff0c;就是在多个页面上需显示相同的内容&#xff0c;例如树状导航&#xff0c;网站导航等。这种情况下可以用博达网站群管理平台中的引用组件功能。引用组件就是与原组件相关联&#xff0c;修改任何一个&#xff0c;其…

书画家•郭晋山•系列作品•赏析之三十三•甲辰龙年第二十九版

[个人简介]&#xff1a; 郭晋山&#xff0c;男&#xff0c;1964年生&#xff0c;祖籍山西繁峙人。 经常欣赏书画名家大作&#xff0c;仔细研究作品之中蕴含的深情厚谊及大自然的美&#xff0c;与作者是如何将内心所想&#xff0c;淋漓尽致地表达在作品之中的&#xff01; [艺术…

我知道要学GIS开发哪些内容,也已经按照框架全部学完了,为什么还是不会开发?还是没有公司要?

大家都知道GIS行业前景和待遇最好的是GIS开发&#xff0c;但是在学校学不到什么核心技能&#xff0c;所以很多同学都想自学。 动手能力强一点的小伙伴们&#xff0c;会自己去找一些GIS开发教程、开源资料库等等来展开自学。这些资料百度上一搜一大把&#xff0c;加个QQ群、微信…

iTOP-3562开发板/核心板应用于人脸跟踪、身体跟踪、视频监控、自动语音识别(ASR)、图像分类驾驶员辅助系统(ADAS)、车牌识别、物体识别等

可应用于人脸跟踪、身体跟踪、视频监控、自动语音识别(ASR)、图像分类驾驶员辅助系统(ADAS)、车牌识别、物体识别等。 iTOP-3562开发板/核心板采用瑞芯微RK3562处理器&#xff0c;内部集成了四核A53Mali G52架构&#xff0c;主频2GHZ&#xff0c;内置1TOPSNPU算力&#xff0c;R…

二叉树剪枝

1、题目解析 2、算法解析 本题使用二叉树的后序遍历&#xff0c;通过递归函数将左右子树进行处理&#xff0c;得到处理结果后&#xff0c;判断左右结果以及自身的val判断是否需要剪枝。 3、代码编写 class Solution { public:TreeNode* pruneTree(TreeNode* root) {if(root …