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
delete
和update
,当添加图形置画布中时,会触发add信号,将其放入对应的栈m_stackcommand
中,使用Ctrl Z实现撤销效果,同时也会将命令和状态的数据存入m_stackUndocommand
和m_stackUndoCommandRecord
中,将其设计成如图所示的数据结构。
按照单一职责的思路,实现的线段样式选择的下拉框和底部页面切换栏控件等,方便后续扩展新功能和维护,一定程度实现项目解耦
当打开多个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;
}
由于文件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));
考虑到保存操作只需要每次保存当前文件(对主程序性能影响较小),暂未做多线程操作处理
通过四个角度可以实现不同方向顶角的三角形;还有梯形,平行四边形等图形
使用单例设计模式,确保只有一个日志实例,使用互斥锁确保多线程环境下的日志写入安全。
按日期分文件:日志文件按日期命名,格式为 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 | 删除 |
功能 | 思路 | 目前情况 |
---|---|---|
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 |
斜率 | 多边形 |