Skip to content

lihaomeng/SVG

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

最终大作业:SVG编辑软件

项目结构

ClassExamProject/
├── CMakeLists.txt
├── SmartFlowChart/ # 主项目目录
│ ├── CMakeLists.txt
│ ├── main.cpp # 程序入口
│ ├── image.qrc # 资源文件
│ ├── commontypes.h # 通用类型定义
│ ├── registereditor.h # 注册编辑器
│ ├── graphicsitem.h/cpp # 图形项基类
│ ├── painterwidget.h/cpp # 绘图窗口
│ ├── flowmainwindow.h/cpp # 主窗口
│ ├── hoverbutton.h/cpp # 悬停按钮
│ ├── svgsavetask.h/cpp # SVG保存任务
│ ├── svgparsetask.h/cpp # SVG解析任务
│ │
│ ├── Graphic/ # 图形组件目录
│ │ ├── circleitem.h/cpp # 圆形
│ │ ├── diamonditem.h/cpp # 菱形
│ │ ├── freelineitem.h/cpp # 自由线
│ │ ├── hexagonitem.h/cpp # 六边形
│ │ ├── lineitem.h/cpp # 直线
│ │ ├── parallelogramitem.h/cpp # 平行四边形
│ │ ├── pentagonitem.h/cpp # 五边形
│ │ ├── rectangleitem.h/cpp # 矩形
│ │ ├── staritem.h/cpp # 星形
│ │ ├── textitem.h/cpp # 文本
│ │ ├── trapezoiditem.h/cpp # 梯形
│ │ └── triangleitem.h/cpp # 三角形
│ │
│ ├── Component/ # 组件目录
│ │ ├── sidebarfactory.h/cpp # 侧边栏工厂
│ │ ├── hoverbuttonhttp.h # HTTP悬停按钮
│ │ └── maincontorller.h # 主控制器
│ │
│ └── image/ # 图片资源目录
│
├── KCustomControl/ # 自定义控件库  dll引入
│ ├── CMakeLists.txt
│ │
│ ├── 按钮控件/
│ │ ├── fontstylebutton.h/cpp # 字体样式按钮
│ │ ├── colorchoosebutton.h/cpp # 颜色选择按钮
│ │ └── pageswitchbar.h/cpp # 页面切换栏
│ │
│ ├── 组合框控件/
│ │ ├── linestylecombobox.h/cpp # 线型组合框
│ │ └── fontsizecombobox.h/cpp # 字体大小组合框
│ │
│ ├── 对话框控件/
│ │ └── colorpickerdialog.h/cpp # 颜色选择对话框
│ │
│ └── 工具提示控件/
│ └── imagetooltip.h/cpp # 图片工具提示
│
└── KLogger/ # 日志库   lib引入
├── CMakeLists.txt
├── klogger.h # 日志类头文件
└── klogger.cpp # 日志类实现

设计亮点(***)

工厂模式应用

设计侧边栏

如果对每个图形绘制对应的侧边栏面板,会存在两个问题
多个图形同时选择时,显示哪一个面板和为每个图形都创建一个面板,造成性能开销浪费
我的设计思路:
要考虑到后期添加图形的属性编辑时,可以使用前面的编写好的代码

通过四个函数生产对应的四个对应的零件Canvas Common Text Special 这四个部分,如下四个函数

    void initSidebarCanvas();
    void initSidebarCommon();
    void initSidebarText();
    void initSidebarSpecial();

每个图形在对应的工厂完成拼装,例如Text文本类型图形,TextSideBar选择 addModule(Canvas); addModule(Font);模块,当选择多个图形时,会通过位运算与运算方法,将所有选择的模块求交集,获取最后显示哪些组件,通过hide()show()方式控制对应不同图形显示不同模块的效果

撤销功能实现

命令模式应用

将所有的操作封装为add deleteupdate,当添加图形置画布中时,会触发add信号,将其放入对应的栈m_stackcommand中,使用Ctrl Z实现撤销效果,同时也会将命令和状态的数据存入m_stackUndocommandm_stackUndoCommandRecord中,将其设计成如图所示的数据结构。

image-20250519160227902

dll和lib封装

按照单一职责的思路,实现的线段样式选择的下拉框和底部页面切换栏控件等,方便后续扩展新功能和维护,一定程度实现项目解耦

单一画布渲染

当打开多个svg文件时,程序只能显示一个画面的内容,因此为每个文件维护一个PainterWidget画布,会造成性能开销大问题 但只需要维护QVector<QList<GraphicsItem*>> m_totalData数据结构,我们不需要在一个图形发生改变时就更新其数据,仅需在页面切换时,接收一个from one to two的信号,更新one和加载two,最后实现了多个文件只需要加载一个PainterWidget

void PainterWidget::onFromCurrentPageToOther(int from, int to)
{
    if (from == to) return;
    m_totalData[from] = m_items;
    m_items = m_totalData[to];
    initParmas();
    update();
    m_currentBottomControlPageIndex = to;
}

多线程操作

svg加载

由于文件I/O读取是性能瓶颈

将文件解析的任务放在异步解析任务中,将其解析数据结果传入在主线程中

QMetaObject::invokeMethod(m_receiver, "handleParsedData", Qt::QueuedConnection, Q_ARG(QList<ParsedItemData>, parsedItems), Q_ARG(QString, m_filename));
QMetaObject::invokeMethod(m_receiver, "handleParseError",  Qt::QueuedConnection, Q_ARG(QString, m_filename));

svg保存

考虑到保存操作只需要每次保存当前文件(对主程序性能影响较小),暂未做多线程操作处理

多个自定义图形

通过四个角度可以实现不同方向顶角的三角形;还有梯形,平行四边形等图形

HTTP请求的日志系统

使用单例设计模式,确保只有一个日志实例,使用互斥锁确保多线程环境下的日志写入安全。

按日期分文件:日志文件按日期命名,格式为 http_YYYY-MM-DD.log

详细记录:时间戳,请求URL和方法,响应状态码,响应数据,错误信息,下列是例子

[2024-01-20 10:30:45.123] REQUEST: GET http://example.com/api
[2024-01-20 10:30:45.456] RESPONSE: http://example.com/api Status: 200
Data: {"linedrawbutton": {...}}
[2024-01-20 10:30:45.789] ERROR: http://example.com/api - Request timeout
logs文件存在的位置
D:\ACodeForWork\projectnew\build\ClassExamProject\SmartFlowChart\logs

实现不足(***)

问题 存在原因 解决思路
缩放功能 初期写代码时未对坐标进行m_scale转换,当缩放后,比例系数发生变化后,移动等功能存在bug 对坐标进行/m_scale处理
旋转功能 初期写代码时,只考虑了0度拉伸边界的情况 不能变动0度拉伸情况的接口,预留好!=0度时的接口,后期继续实现
qss代码难维护问题 单独抽离
注册表直接使用地址 后期更改
结构体,枚举类型管理混乱 后期更改,单独用文件记录

使用方法

按键 主要功能
Ctrl + A 全选图形
Ctrl + C 复制
Ctrl + V 粘贴
Ctrl + X 剪贴
Ctrl + Z 撤销图形
Ctrl + shift + Z 撤销Ctrl Z
BackSpace/Del 删除

重要类和API介绍


测试接口

功能 思路 目前情况
2.15 文件管理
新建画布 直接建立一个新的PainterWidget效率太低了,使用 √ 底部界面需要优化
SVG保存 多线程 只实现了单线程,多线程和异常处理
SVG加载 多线程 存在bug
png 图片导出 让用户指定路径,是否可以存放在注册表中,
2.16 配置管理
本地配置 使用了绝对路径,需要修改
在线配置 请求HTTP,成功后,再加载
模式 类型
选择
矩形 Rect
直线 Line
圆形/椭圆 Circle
菱形 Diamond
五边形 Pentagon
六边形 Hexagon
五角星 Star
三角形 Triangle
自由线 FreeLine
文字 Text
平行四边形 Parallelogram
梯形 Trapezoid
放大 -
缩小 -
类型 特殊性 SVG格式
RectType 考虑圆角矩形 矩形
CircleType 椭圆
LineType 直线
DiamondType 多边形
StarType 多边形
HexagonType 多边形
PentagonType 多边形
TriangleType 顶角方向 多边形
FreeLineType QVetor<QPoint> 多段线
TextType text 文本
ParallelogramType 斜率 多边形
TrapezoidType 斜率 多边形

About

QT版 SVG编辑器

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published