基于Qt实现的轻量级CAD画图软件

1.界面展示 

2.功能展示

3.关于Graphics View绘图架构

     由于QPainter画图形,不能实现对图形的选择、编辑、移动等操作,所以我的整个项目是基于Craphics View绘图架构来实现的

3.1 Craphics View

(1)Craphics View绘图架构介绍        

Craphics View架构主要分为三个部分:视图、场景、图形项(图元)

  • QGraphicsScene(场景):可以管理多个图形项
  • QGraphicsItem(图形项):也就是图元,支持鼠标事件响应。
  • QGraphicsView(视图):关联场景可以让场景中的所有图形项可视化

场景、视图、图元三者的关系图:

(2)QGrphicsView中一些常用操作接口

//添加场景

//设置关联显示的场景

void QGraphicsView::setScene(QGraphicsScene *scene)

// 设置场景在视图中可视部分的矩形区域

void QGraphicsView::setSceneRect(const QRectF &rect)

//场景外观设置操作

//设置场景在视图中的对齐方式,缺省是上下都居中

 void QGraphicsView::setAlignment(Qt::Alignment alignment)

//设置场景场景的背景画刷

void QGraphicsView::setBackgroundBrush(const QBrush &brush)

//设置场景的前景画刷

void QGraphicsView::setForegroundBrush(const QBrush &brush)

//设置视图的绘图选项

 void QGraphicsView::setRenderHints(QPainter::RenderHints hints)

 //交互

//是否允许场景可交互,如果禁止交互,则任何键盘或鼠标操作都被忽略

void QGraphicsView::setInteractive(bool allowed)

//返回选择矩形框

 QRect QGraphicsView::rubberBandRect() const

//选择模式 ,参数为枚举类型Qt : : ltemSelectionMode

 Qt::ItemSelectionMode rubberBandSelectionMode() const

//获取视图坐标系中某个位置处的图形项

QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const
QGraphicsItem *QGraphicsView::itemAt(int x, int y) const

//获取场景中的所有、或者某个选择区域内图形项目的列表

QList<QGraphicsItem *> QGraphicsView::items() const
QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
QList<QGraphicsItem *> QGraphicsView::items(int x, int y) const
....

//坐标

//将场景中的一个坐标转换为视图的坐标

QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const

//将视图中的一个坐标转换为场景的坐标

 QPointF QGraphicsView::mapToScene(const QPoint &point) const

(3)QGraphicsScene中一些常用操作接口

//场景

//设置场景的矩形区

​​​​​​​void QGraphicsScene::setSceneRect(const QRectF &rect)

//分组

//创建图形项组

QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)

//解除一个图形项组

void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)

 //输入焦点

//返回当前获得焦点的图形项

QGraphicsItem *QGraphicsScene::focusItem() const

//去除选择焦点

void QGraphicsScene::clearFocus()

//视图是否有焦点

 bool QGraphicsScene::hasFocus() const

//图形项的操作

//添加一个已经创建的图形项

void QGraphicsScene::addItem(QGraphicsItem *item) 

//删除图形项

 void QGraphicsScene::removeItem(QGraphicsItem *item)

//清除所有图形项

[slot] void QGraphicsScene::clear()

//返回鼠标抓取的图形项

QGraphicsItem *QGraphicsScene::mouseGrabberItem() const

//返回选择的图形项列表

QList<QGraphicsItem *> QGraphicsScene::selectedItems() const

//清除所有选择

[slot] void QGraphicsScene::clearSelection()

//获取某个位置处的顶层图形项

QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) constQGraphicsItem *QGraphicsScene::itemAt(qreal x, qreal y, const QTransform &deviceTransform) const

//返回某个矩形区域、多边形等选择区域内的图形项列表

QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order = Qt::DescendingOrder) const

//添加图形项

//添加一个椭圆
QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());//添加一条直线
QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen());//添加一个绘图路径
QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush());//添加一个图片
QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap);//添加一个多边形
QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush());//添加一个矩形
QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());//添加简单文字
QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString &text, const QFont &font = QFont());//添加字符串
QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font = QFont());//添加界面组件
QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags = Qt::WindowFlags());

 (4)QGraphicsItem中一些常用操作接口

//属性设置

//设置图形项的操作属性,例如,可选择,可移动等

void QGraphicsItem::setFlags(QGraphicsItem::GraphicsItemFlags flags)

//设置透明度

void QGraphicsItem::setOpacity(qreal opacity)

//设置图形效果

void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)

//图形项是否被选中

void QGraphicsItem::setSelected(bool selected)

//用户自定义数据

void QGraphicsItem::setData(int key, const QVariant &value)

//坐标

//图形项的X坐标

void QGraphicsItem::setX(qreal x)

//图形项的Y坐标

void QGraphicsItem::setY(qreal y)

//图形项的Z值,Z值控制图形项的叠放次序

void QGraphicsItem::setZValue(qreal z)

//图形项在父项中的位置

void QGraphicsItem::setPos(const QPointF &pos)

//返回图形项在场景中的坐标,相当于调用mapToScene(0,0)

QPointF QGraphicsItem::scenePos() const

//坐标变换 

//复位坐标系,取消所有坐标变换

void QGraphicsItem::resetTransform()

//旋转一定角度,参数为正数时表示顺时针旋转

void QGraphicsItem::setRotation(qreal angle)

//按比例缩放,缺省值为1

void QGraphicsItem::setScale(qreal factor)

//坐标映射 

//将另一个图形项的一个点映射到本图形项到坐标系

QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const

//将父项的一个点映射到本图形项的坐标系

QPointF QGraphicsItem::mapFromParent(const QPointF &point) const

//将场景中的一个点映射到本图项到坐标系

QPointF QGraphicsItem::mapFromScene(const QPointF &point) const

//将本图形项内到一个点映射到另一个图形项的坐标系

QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
...

//将本图形项内的一个点映射到父项坐标系

QPointF QGraphicsItem::mapToParent(const QPointF &point) const
QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const

//将本图形项内到一个点映射到场景坐标系

QPointF QGraphicsItem::mapToScene(const QPointF &point) const
QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const

4.项目整体结构

4.1 项目中使用的类

项目总结:

项目上遇到的一些问题:

        1.开始在tabWidget上添加画布时,不能做画,选择要画的图形后,一点击画笔程序就崩溃退出,然后我添加了一些判定条件,如果tabWidget->currentIndex() < 0时,指针赋值失败,后来加了判断条件后,就可以了,再后来我直接改进,打开应用程序窗口时,就在会在tabWidget上创建画布。

        2.在mainwindow.cpp中我重写了mouseDoubleClickEvent方法,双击图形时,更新右边的属性列表,但是在双击空白的视图view时程序就会闪退,后来使用的解决方法就是加了判定条件,如果已经选择了图形,双击图形就更新属性列表,如果没有选择图形,只单纯的双击画布,就忽视事件。具体代码实现如下:

//双击图形更新图形的属性列表
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{   QGraphicsScene * scene = m_scene;if (scene && !scene->selectedItems().isEmpty()) {if (scene->selectedItems().first()->isSelected()) {updateItemProperty(); //更新属性列表}}else{event->ignore();}
}

        3.在按下如下按钮时,如果图形没有被选中,程序会崩溃闪退,后来我加了一些判定条件,比如在选中的图形大于1时才能进行组合、对齐和拉伸等操作 ,该问题也完美解决

void MainWindow::aglin() {graphicsScene * scene = dynamic_cast<graphicsScene*>(m_scene);int selectedItemCount = scene->selectedItems().count();if(ui->tabWidget->currentIndex() >= 0 && scene && selectedItemCount > 1){if (sender() == ui->top_align_button){scene->align(TOP_ALIGN);}else if(sender() == ui->bottom_align_button){scene->align(BOTTOM_ALIGN);}else if(sender() == ui->left_align_button){scene->align(LEFT_ALIGN);}else if(sender() == ui->right_align_button){scene->align(RIGHT_ALIGN);}else if(sender() == ui->horizontal_align){scene->align(HORZEVEN_ALIGN);}else if(sender() == ui->vertical_align){scene->align(VERTEVEN_ALIGN);}else if(sender() == ui->vertical_space_Button){scene->align(HORZEVEN_SPACE);}else if(sender() == ui->horizontal_space_Button){scene->align(VERTEVEN_SPACE);}else if(sender() == ui->widthButton){scene->align(WIDTH_ALIGN);}else if(sender() == ui->heightButton){scene->align(HEIGHT_ALIGN);}}
}

        以上就是我在开发时遇到的一些问题,当然还有一些小问题,就不一一阐述了。

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

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

相关文章

【计算机视觉】3D视觉

文章目录 一、基本问题二、三个坐标系 X w \boldsymbol{X}_w Xw​到 X c \boldsymbol{X}_c Xc​的转换 X c \boldsymbol{X}_c Xc​到 x i \boldsymbol{x}_i xi​的转换投影矩阵尺度模糊问题 三、相机标定四、立体视觉 我的《计算机视觉》系列参考UC Berkeley的CS180课程&#x…

【机器学习】项目数据处理部分

文章目录 前言项目理解数据探索特征工程总结 前言 本文参考《阿里云天池大赛赛题解析》&#xff0c;拿到一个项目或者赛题&#xff0c;使用机器学习来进行预测分类&#xff0c;需要以下七个步骤&#xff1a; 项目&#xff08;赛题&#xff09;理解数据探索特征工程模型训练模…

buuctf_练[GYCTF2020]FlaskApp

[GYCTF2020]FlaskApp 文章目录 [GYCTF2020]FlaskApp常用绕过方法掌握知识解题思路解题一 -- 计算pin码解题二 -- 拼接绕过 执行命令 关键paylaod 常用绕过方法 ssti详解与例题以及绕过payload大全_ssti绕过空格_HoAd’s blog的博客-CSDN博客 CTF 对SSTI的一些总结 - FreeBuf网…

直线模组怎么分类?

直线模组是一种广泛应用于自动化设备、机器人、数控机床、电子设备等领域的精密传动系统。根据不同的分类方式&#xff0c;直线模组可分为多种类型。 一、按照轴数分类 1、单轴直线模组&#xff1a;只有一个移动轴的直线模组&#xff0c;通常用于简单的直线运动和定位。 2、双…

linux常用基本命令大全的使用(三)

&#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页石马农青衿 &#x1f304;每日一句&#xff1a;努力一点&#xff0c;优秀一点 &#x1f4d1;前言 本文主要是linux常用基本命令面试篇文章&#xff0c;如果有什么…

如何在Postman中使用静态HTTP

首先&#xff0c;打开 Postman 软件。在 Postman 的菜单栏中&#xff0c;点击 “Preferences”&#xff08;偏好设置&#xff09;。 亲身经验&#xff1a;我自己尝试了这个方法&#xff0c;发现它非常适用于需要使用HTTP的场景。 数据和引证&#xff1a;根据 Postman 官方文档…

基于VectorGrid加载GeoServer发布的矢量瓦片实例

目录 前言 一、关于VectorGrid 1、开源地址 2、本地示例 二、与LeafLet集成 1、新建html页面 2、地图初始化 3、pbf瓦片地址配置 4、pbf初始化 三、GeoServer跨域问题 1、web.xml配置 2、重启tomcat 总结 前言 回望10月&#xff0c;发生了一些变动&#xff0c;面向未…

设计模式——单例模式详解

目录 设计模式类型单例模式单例模式方式饿汉式静态常量方式静态代码块形式 懒汉式线程不安全&#xff08;不推荐&#xff09;懒汉式优化&#xff08;不推荐&#xff09; 双重检查&#xff08;推荐方式&#xff09;静态内部类&#xff08;推荐方式&#xff09;枚举方式&#xff…

分类预测 | MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双向门控循环单元数据分类预测

分类预测 | MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双向门控循环单元数据分类预测 目录 分类预测 | MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双向门控循环单元数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现SSA-CNN-BiGRU麻雀算法优化卷积双…

axios封装以及详细用法

文章目录 axios用法(这里没有封装&#xff0c;下面有封装好的get&#xff0c;post方法&#xff0c;在axios封装里面)get &#xff0c;delete方法post&#xff0c;put方法 axios具体封装axios 具体参数配置 axios用法(这里没有封装&#xff0c;下面有封装好的get&#xff0c;pos…

信息检索与数据挖掘 | 【实验】排名检索模型

文章目录 &#x1f4da;实验内容&#x1f4da;相关概念&#x1f4da;实验步骤&#x1f407;分词预处理&#x1f407;构建倒排索引表&#x1f407;计算query和各个文档的相似度&#x1f407;queries预处理及检索函数&#x1f525;对输入的文本进行词法分析和标准化处理&#x1f…

基于Threejs开发的3D点位编辑器

简介 编辑器可以让用户在3D场景中添加、编辑和删除点位&#xff0c;并且支持上传参考模型、多点位类型的添加、上传、编辑、下载和删除、场景视图中点位的拖拽、场景配置等功能。 注&#xff1a;所有操作均在本地。 技术栈 three.js&#xff1a;一个用于创建3D图形的JavaScr…

IOC课程整理-17 Spring事件

1. Java 事件/监听器编程模型 2. 面向接口的事件/监听器设计模式 3. 面向注解的事件/监听器设计模式 4. Spring 标准事件-ApplicationEvent 5. 基于接口的 Spring 事件监听器 6. 基于注解的 Spring 事件监听器 7. 注册 Spring ApplicationListener 8. Spring 事件发布器 9. Spr…

java springboot2.7 写一个本地 pdf 预览的接口

依赖方面 创建的是 接口web项目就好了 然后包管理工具打开需要这些 import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; imp…

14 结构性模式-适配器模式

1 适配器模式介绍 适配器模式(adapter pattern )的原始定义是&#xff1a;将类的接口转换为客户期望的另一个接口&#xff0c;适配器可以让不兼容的两个类一起协同工作。 2 适配器模式原理 3 适配器模式应用实例 /*** SD卡接口**/ public interface SDCard {//读取SD卡Strin…

安信可小安派AiPi 代码下载

安信可小安派AiPi 代码下载笔记记录 AiPi 代码下载&#xff08;直接使用命令行操作&#xff0c;仅需要Type-C接口线即可&#xff09; 在完成环境搭建&#xff0c;和代码编写前提下&#xff0c;使用Type-C接口线下载代码&#xff0c;当然可以自己使用usb-ttl串口线下载程序&am…

非遗主题网站的设计与实现基于PHP实现

包括源码参考论文 下载地址: https://juzhendongli.store/commodity/details/18

【C】想练习C语言?通讯录的实现了解一下

目录 实现思路 开始实现 添加增加联系人功能 添加显示联系人信息的功能 添加删除联系人功能 添加查找指定联系人的功能 添加修改指定联系人的功能 测试 代码 Test.c Contact.c Contact.h 实现思路 1.通讯录中保存人的信息&#xff1a;名字、年龄、性别、电话、住址…

大语言模型(LLM)综述(三):大语言模型预训练的进展

A Survey of Large Language Models 前言4. PRE-TRAINING4.1数据收集4.1.1 数据源4.1.2 数据预处理4.1.3 预训练数据对LLM的影响 4.2 模型架构4.2.1 典型架构4.2.2 详细配置4.2.3 预训练任务4.2.4 解码策略4.2.5 总结和讨论 4.3 模型训练4.3.1 优化设置4.3.2 可扩展的训练技术 …

MySQL 字符集与乱码与collation设置的问题?

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友…