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

news2024/12/28 23:14:35

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) const

QGraphicsItem *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.coloradmin.cn/o/1135574.html

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

相关文章

js echarts 词云图

<!DOCTYPE html> <html><head><meta charset"utf-8" /><title>词云图</title><script src"./echarts.js"></script><script src"./echarts-wordcloud.js"></script></head>&…

vivado简单仿真入门

打开软件 创建工程 create project ![在这里插入图片描述](https://img-blog.csdnimg.cn/892eda626d394733920854b71ca8f726.png)先next,保留工程路径&#xff0c;配置环境 配置芯片环境 本次芯片类型 xc7k325tffg900-2 创建之后完整的demo 编写仿真内容 timescale 1ns/1…

一、高效构建Java应用:Maven入门和进阶

一、高效构建Java应用&#xff1a;Maven入门和进阶 目录 一、Maven简介和快速入门 1.1 Maven介绍1.2 Maven主要作用理解1.3 Maven安装和配置 二、基于IDEA的Maven工程创建 2.1梳理Maven工程GAVP属性2.2 Idea构建Maven JavaSE工程2.3 Idea构建Maven JavaEE工程2.4 Maven工程项…

态路小课堂丨InfiniBand AOC有源光缆简介

TARLUZ态路 InfiniBand&#xff08;直译为“无限带宽”技术&#xff0c;缩写为IB&#xff09;是一个用于高性能计算的计算机网络通信标准&#xff0c;它具有极高的吞吐量和极低的延迟&#xff0c;用于计算机与计算机之间的数据互连。InfiniBand也用作服务器与存储系统之间的直…

如何在《阴阳师》游戏中使用单机单窗口软件工具进行防封技巧?

如何在《阴阳师》游戏中使用单机单窗口软件工具进行防封技巧&#xff1f; 首先&#xff0c;定义在《阴阳师》游戏中&#xff0c;使用单机单窗口软件工具进行防封技巧涉及到如何安装和配置软件&#xff0c;以及如何在游戏中应用这些技巧。 我曾经使用过在《阴阳师》游戏中防封…

Fatal error in launcher: Unable to create process using

python在安装库的时候报如下错误&#xff1a; Fatal error in launcher: Unable to create process using "e:\python3.8.8\python.exe" "D:\python3.8.8\Scripts\pip.exe" install qrcode[pil]: ??????????? 除了卸载重装之外&#xff0c;还…

zk-Bench:SNARKs性能对比评估工具

1. 引言 JENS ERNSTBERGER等人2023年论文《zk-Bench: A Toolset for Comparative Evaluation and Performance Benchmarking of SNARKs》。 zk-Bench&#xff0c;定位为&#xff1a; 定位为首个公钥密码学性能评估基准测试框架和工具&#xff0c;重点关注通用ZKP系统的实测评…

JVS规则引擎决策流:轻松解决规则执行中的潜在问题

规则引擎的在线调试功能是指用户在编辑、创建或修改规则时&#xff0c;可以实时地测试这些规则执行的效果&#xff0c;以便及时发现和解决潜在的问题。 接下来我们详细看看在线调试的功能&#xff1a; 1、配置对应的规则&#xff08;这里略过&#xff09;如下图所示&#xff…

蓝桥云课--1024 第 2 场算法双周赛

2-铺地板【算法赛】&#xff08;找规律&#xff09; 一、题目要求 二、思路 &#xff08;1&#xff09;因为每块地砖都是2*3的规格&#xff1a; 1.n<2或者m<2的时候&#xff0c;则不能使用上述规格的瓷砖 No 2.n<3或者m<3的时候&#xff0c;也不能使用上述规格…

项目管理中,如何建立里程碑式管理?

项目进度控制是项目管理中的重要环节&#xff0c;也是最具挑战性的工作之一。在项目管理中&#xff0c;项目进度失控受到多种因素的影响&#xff0c;导致项目失控。 为了解决这个问题&#xff0c;我们可以借鉴在旅途中学到的经验&#xff0c;通过设立里程碑来了解项目进度&am…

macOS 12 Monterey v12.7.1正式版:开启全新的操作系统体验

macOS 12 Monterey已经向所有兼容的Mac设备推出&#xff0c;为您带来了一系列强大的新功能和改进。这个全新的操作系统版本&#xff0c;不仅带来了更流畅的用户体验&#xff0c;还增强了与iOS设备的无缝集成&#xff0c;让您的设备使用更加高效&#xff0c;更加便捷。 macOS 1…

一文说尽零售数据分析指标体系

零售的本质业务模式是通过在各种渠道上吸引客户来购买我们的商品来实现盈利&#xff0c;其实就是客户-渠道-商品&#xff0c;也就是我们常说的“人、场、货”&#xff0c;除此之外还有供应链、财务等起到重要的辅助作用。因此如果要构建起系统化的零售数据分析指标体系&#xf…

压敏电阻有哪些原理?|深圳比创达电子EMC

压敏电阻是一种金属氧化物陶瓷半导体电阻器。它以氧化锌(ZnO)为基料&#xff0c;加入多种(一般5&#xff5e;10种)其它添加剂&#xff0c;经压制成坯体&#xff0c;高温烧结&#xff0c;成为具有晶界特性的多晶半导体陶瓷组件。氧化锌压敏电阻器的微观结构如下图1所示。 氧化锌…

linux 内存检测工具 kfence 详解(二)

系列博文&#xff1a; linux 内存检测工具 kfence 详解(一) linux 内存检测工具 kfence 详解(二) 回上一篇博文 0. 前言 kfence虽然代码不多&#xff0c;但设计的内容、逻辑比较多。为了更加清晰、轻松地理解kfence&#xff0c;笔者将其知识点分两篇博文&#xff1a; 第一篇…

美海军用于情报、监视和侦察的中大型无人系统概述

源自&#xff1a;中国指挥与控制学会 “人工智能技术与咨询” 发布 简 介 1 引 言 2 超大型无人潜航器 图1 波音“回声航行者”无人潜航器 图2 “虎鲸”超大型无人潜航器 3 中型无人水面舰艇 图3 “海鹰”无人水面舰艇 图4 “海上猎人”无人水面舰艇 4 …

今天玩到一个微信钓鱼小游戏,很有趣,居然还能玩萝卜刀

这款钓鱼冠军微信小游戏很有创意&#xff0c;除了传统的钓鱼玩法&#xff0c;居然还融合了黄金矿工的玩法&#xff0c;很不错的想法&#xff0c;而且居然还能玩最近比较火的萝卜刀&#xff0c;快来扫码体验一下吧&#xff0c;或者微信里搜索 《钓鱼冠军》小游戏&#xff0c;认…

Python轮廓追踪【OpenCV形态学操作】

文章目录 概要代码运行结果 概要 一些理论知识 OpenCV形态学操作理论1 OpenCV形态学操作理论2 OpenCV轮廓操作|轮廓类似详解 代码 代码如下&#xff0c;可以直接运行 import cv2 as cv# 定义结构元素 kernel cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) # print kern…

YOLOv8官方教程:如何训练模型

文章目录 一、简介二、YOLOv8的优点train模式特色 三、训练3.1 单 GPU 和 CPU 训练示例3.2 多GPU训练3.3 Apple M1 和 M2 MPS 训练3.4 恢复中断的训练 四、其他参数五、训练Log5.1 Comet5.2 ClearML5.3 TensorBoard 一、简介 本文介绍YOLOv8如何在单GPU、多GPU和Apple设备上训…

家用小型洗衣机哪款性价比高?热门内衣洗衣机测评

随着现代社会的快速发展&#xff0c;洗衣机已经成为了家家必备的电器产品。但是我们清洗贴身衣物的话&#xff0c;并不能直接扔进洗衣机里面洗&#xff0c;主要原因就是会与其他的衣物产生交叉的感染&#xff0c;而且又不能更好地除去贴身衣物上的细菌&#xff0c;因此一台内衣…

带着问题去分析:Spring Bean 生命周期 | 京东物流技术团队

1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_接口&#xff0c;BeanDefinition里面存储的就是我们编写的Java类在Spring中的元数据&#xff0c;包括了以下主要的元数据信息&#xff1a; 1&…