乐于分享
好东西不私藏

赶紧收藏!商用级工业制图软件源码开源分享

赶紧收藏!商用级工业制图软件源码开源分享

欢迎来到【Qt开发宝典】微信公众号【知识宝库】!

本期【C++高级工程师】动手实战系列,第142期。本期我们聚焦一个兼具实用性与学习深度的主题——👉《赶紧收藏!商用级工业制图软件源码开源分享》。本系列文章旨在为关注Qt跨平台开发、Linux C++后端及系统底层架构的开发者,提供一个系统的学习参考。内容将通过原理讲解与实战结合的方式,解析相关核心知识与设计思路,以期对您的技术探索与实践有所裨益。

👉欢迎关注【Qt开发宝典】微信公众号

🚀定期分享更多Linux C++/Qt等技术干货!!!

一、【工程项目运行】

1. 基础图形–网格
2. 基础图形–无网格
3. 基础图形–保存
4. 电气符号–网格
5. 电气符号–无网格
6. 电气符号–保存
7. 工程制图软件–流程图符号
8. 工程制图软件–保存
9. 工程制图软件–打开图形
10. 工程制图软件–关于
二、【工程项目简介】

2.1 项目简介

工程制图软件是一款基于Qt 6/C++17开发的桌面端二维工程绘图应用。项目使用Qt Widgets与Graphics View Framework构建绘图画布,支持基础几何图形、电气符号、流程图符号的绘制与拖拽创建,并提供文件保存/加载、撤销重做、属性编辑、网格显示、对象捕捉、图层模型、测量工具等功能。

当前应用名称与窗口标题为工程制图软件 v1.0,默认工程文件扩展名为.edw,底层采用XML文本格式保存。

2.2 使用技术栈

| 分类 | 技术 |

| ——— | —– |

| 编程语言 | C++17 |

| GUI 框架 | Qt 6 Widgets |

| 绘图框架 | Qt Graphics View Framework |

| 文件格式 | XML / .edw |

| 撤销重做 | Qt Undo Framework / QUndoStack |

| 资源系统 | Qt Resource System / .qrc |

| 构建系统 | qmake |

| 推荐环境 | Qt 6.5.x、MinGW 64-bit、Windows 10/11 |

2.3 功能特性

【文件管理】

– 新建工程图

– 打开.edw工程图文件

– 保存当前工程图

– 另存为工程图

– 关闭窗口时检测绘图区内容并提示保存

– 使用XML保存图层与图形对象

– 支持底层网表文本生成接口

【绘图能力】

工具栏和菜单支持以下绘制模式:

– 选择

– 直线

– 圆

– 矩形

– 折线

– 样条曲线

– 图形连线

状态栏会根据当前工具显示操作提示,例如绘制直线、绘制圆、绘制折线、绘制样条曲线和连接图形等。

【组件库】

左侧组件库支持拖拽组件到绘图区域创建图形,分为三类。

【基础图形】

– 直线 Line

– 圆 Circle

– 椭圆 Ellipse

– 圆弧 Arc

– 扇形 Sector

– 多边形 Polygon

– 星形 Star

– 矩形 Rectangle

– 圆角矩形 RoundedRect

– 箭头 Arrow

– 文本框 TextBox

– 折线 Polyline

– 样条曲线 Spline

【电气符号】

– 普通二极管 Diode

– 变容二极管 VaricapDiode

– NPN 三极管 NPNTransistor

– PNP 三极管 PNPTransistor

– 电阻 Resistor

– 电容 Capacitor

– 电感 Inductor

– 开关 Switch

– 接地 Ground

– 电源 PowerSupply

【流程图符号】

– 开始/结束 Terminator

– 处理 Process

– 判断 Decision

– 数据 Data

– 文档 Document

– 连接器 Connector

【属性编辑】

右侧属性面板支持对选中图形进行属性查看与编辑,主要包括:

– 图形名称

– 画笔宽度

– 画笔颜色

– 填充颜色

– 部分图形的专有属性显示

【视图操作】

– 抗锯齿绘制

– 平滑图像变换

– 橡皮筋框选

– Ctrl + 鼠标滚轮 缩放

– 鼠标中键拖动画布平移

– 放大、缩小、适应窗口

– 以鼠标位置为缩放锚点

【网格与捕捉】

GridManager 支持:

– 显示/隐藏网格

– 设置网格大小

– 设置网格颜色

– 在场景背景中绘制网格

SnapManager 支持的捕捉类型:

– NoSnap

– EndPoint

– MidPoint

– Center

– Intersection

– Grid

– All

【图层管理】

项目包含图层模型与图层管理器,支持:

– 创建图层

– 删除图层

– 清空图层

– 设置当前图层

– 查找图层

– 图层可见性

– 图层锁定状态

– 图层颜色

– 图形与图层关联

图层信息会保存到.edw文件中。

【撤销与重做】

基于QUndoStack实现撤销重做,包含命令类:

–AddShapeCommand:添加图形

–RemoveShapeCommand:删除图形

–MoveShapeCommand:移动图形

–ChangePropertyCommand:修改图形属性

快捷键:

– 撤销:Ctrl + Z

– 重做:平台默认重做快捷键,通常为 Ctrl + Y

【测量工具】

菜单 工具 中提供:

– 测量距离

– 测量角度

– 测量面积

2.3 工程目录结构

EngineeringDrawingSoftware/├── EngineeringDrawingSoftware.pro      # qmake 工程文件├── main.cpp                            # 程序入口├── mainwindow.h/.cpp                   # 主窗口、菜单、工具栏、停靠窗口├── drawingscene.h/.cpp                 # 绘图场景、图形创建与交互├── drawingview.h/.cpp                  # 绘图视图、缩放、平移、拖拽投放├── shape.h/.cpp                        # 图形抽象基类├── filemanager.h/.cpp                  # 文件保存、加载、网表生成├── commands.h/.cpp                     # 撤销/重做命令├── propertyeditor.h/.cpp               # 属性编辑器├── componentlibrary.h/.cpp             # 组件库├── componentlistwidget.h/.cpp          # 可拖拽组件列表├── layer.h/.cpp                        # 图层模型├── layermanager.h/.cpp                 # 图层管理器├── gridmanager.h/.cpp                  # 网格管理器├── snapmanager.h/.cpp                  # 捕捉管理器├── measuretool.h/.cpp                  # 测量工具├── port.h/.cpp                         # 图形端口模型├── resizehandle.h/.cpp                 # 调整大小手柄├── *shape.h/.cpp                       # 各类图形、符号、流程图组件├── images.qrc                          # Qt 资源文件├── images/│   └── logo.ico                        # 应用图标└── build/                              # 构建输出目录

2.4 系统架构设计

项目采用分层设计:

用户界面层├── MainWindow├── ComponentLibrary└── PropertyEditor视图交互层└── DrawingView / QGraphicsView场景控制层├── DrawingScene / QGraphicsScene├── GridManager├── SnapManager├── LayerManager└── QUndoStack图形对象层├── Shape├── 基础几何图形├── 电气符号├── 流程图符号├── ConnectionShape├── Port└── ResizeHandle数据持久化层├── FileManager├── QXmlStreamWriter└── QXmlStreamReader

三、【工程项目】部分源码

1. mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QUndoStack>class DrawingView;class DrawingScene;class PropertyEditor;class LayerManager;class SnapManager;class GridManager;class QToolBar;class QDockWidget;class QComboBox;class QSpinBox;class ComponentLibrary;class MainWindow : public QMainWindow{    Q_OBJECTpublic:    MainWindow(QWidget *parent = nullptr);    ~MainWindow();private slots:    voidnewFile();    voidopenFile();    voidsaveFile();    voidsaveFileAs();    voidundo();    voidredo();    voiddrawLine();    voiddrawCircle();    voiddrawRectangle();    voiddrawPolyline();    voiddrawSpline();    voiddrawConnection();    voidselectMode();    voiddeleteSelected();    voidmeasureDistance();    voidmeasureAngle();    voidmeasureArea();    voidtoggleGrid();    voidtoggleSnap();    voidzoomIn();    voidzoomOut();    voidzoomFit();    voidshowAbout();    voidonPenWidthChanged(int width);    voidonPenColorChanged();    voidonBrushColorChanged();protected:    voidcloseEvent(QCloseEvent *event) override;private:    voidcreateActions();    voidcreateMenus();    voidcreateToolBars();    voidcreateDockWidgets();    voidcreateStatusBar();    DrawingView *m_view;    DrawingScene *m_scene;    PropertyEditor *m_propertyEditor;    ComponentLibrary *m_componentLibrary;    LayerManager *m_layerManager;    SnapManager *m_snapManager;    GridManager *m_gridManager;    QUndoStack *m_undoStack;    QString m_currentFile;    QToolBar *m_fileToolBar;    QToolBar *m_editToolBar;    QToolBar *m_drawToolBar;    QToolBar *m_viewToolBar;    QSpinBox *m_penWidthSpinBox;    QMenu *m_fileMenu;    QMenu *m_editMenu;    QMenu *m_drawMenu;    QMenu *m_viewMenu;    QMenu *m_toolsMenu;    QMenu *m_helpMenu;    QAction *m_newAction;    QAction *m_openAction;    QAction *m_saveAction;    QAction *m_saveAsAction;    QAction *m_exitAction;    QAction *m_undoAction;    QAction *m_redoAction;    QAction *m_deleteAction;    QAction *m_selectAction;    QAction *m_lineAction;    QAction *m_circleAction;    QAction *m_rectangleAction;    QAction *m_polylineAction;    QAction *m_splineAction;    QAction *m_connectionAction;    QAction *m_measureDistanceAction;    QAction *m_measureAngleAction;    QAction *m_measureAreaAction;    QAction *m_gridAction;    QAction *m_snapAction;    QAction *m_zoomInAction;    QAction *m_zoomOutAction;    QAction *m_zoomFitAction;    QAction *m_aboutAction;};#endif // MAINWINDOW_H
2. mainwindow.cpp
#include "mainwindow.h"#include "drawingview.h"#include "drawingscene.h"#include "propertyeditor.h"#include "componentlibrary.h"#include "layermanager.h"#include "snapmanager.h"#include "gridmanager.h"#include "filemanager.h"#include "measuretool.h"#include <QMenuBar>#include <QToolBar>#include <QStatusBar>#include <QDockWidget>#include <QFileDialog>#include <QMessageBox>#include <QSpinBox>#include <QLabel>#include <QPushButton>#include <QColorDialog>#include <QActionGroup>#include <QCloseEvent>MainWindow::MainWindow(QWidget *parent)    : QMainWindow(parent)    , m_currentFile(""){    setWindowTitle("工程制图软件 v1.0");    resize(1200, 800);    // 创建管理器    m_layerManager = new LayerManager(this);    m_snapManager = new SnapManager();    m_gridManager = new GridManager();    m_undoStack = new QUndoStack(this);    // 创建场景和视图    m_scene = new DrawingScene(m_layerManager, m_undoStack, this);    m_scene->setSnapManager(m_snapManager);    m_scene->setGridManager(m_gridManager);    m_view = new DrawingView(m_scene, this);    setCentralWidget(m_view);    connect(m_view, &DrawingView::componentDropped,            m_scene, &DrawingScene::onComponentDroppedAt);    // 创建UI组件    createActions();    createMenus();    createToolBars();    createDockWidgets();    createStatusBar();    statusBar()->showMessage("就绪", 2000);}MainWindow::~MainWindow(){    delete m_snapManager;    delete m_gridManager;}void MainWindow::createActions(){    // 文件操作    m_newAction = new QAction("新建(&N)", this);    m_newAction->setShortcut(QKeySequence::New);    connect(m_newAction, &QAction::triggered, this, &MainWindow::newFile);    m_openAction = new QAction("打开(&O)...", this);    m_openAction->setShortcut(QKeySequence::Open);    connect(m_openAction, &QAction::triggered, this, &MainWindow::openFile);    m_saveAction = new QAction("保存(&S)", this);    m_saveAction->setShortcut(QKeySequence::Save);    connect(m_saveAction, &QAction::triggered, this, &MainWindow::saveFile);    m_saveAsAction = new QAction("另存为(&A)...", this);    m_saveAsAction->setShortcut(QKeySequence::SaveAs);    connect(m_saveAsAction, &QAction::triggered, this, &MainWindow::saveFileAs);    m_exitAction = new QAction("退出(&X)", this);    m_exitAction->setShortcut(QKeySequence::Quit);    connect(m_exitAction, &QAction::triggered, this, &QWidget::close);    // 编辑操作    m_undoAction = m_undoStack->createUndoAction(this, "撤销(&U)");    m_undoAction->setShortcut(QKeySequence::Undo);    m_redoAction = m_undoStack->createRedoAction(this, "重做(&R)");    m_redoAction->setShortcut(QKeySequence::Redo);    m_deleteAction = new QAction("删除(&D)", this);    m_deleteAction->setShortcut(QKeySequence::Delete);    connect(m_deleteAction, &QAction::triggered, this, &MainWindow::deleteSelected);    // 绘图工具    m_selectAction = new QAction("选择", this);    m_selectAction->setCheckable(true);    m_selectAction->setChecked(true);    connect(m_selectAction, &QAction::triggered, this, &MainWindow::selectMode);    m_lineAction = new QAction("直线", this);    m_lineAction->setCheckable(true);    connect(m_lineAction, &QAction::triggered, this, &MainWindow::drawLine);    m_circleAction = new QAction("圆", this);    m_circleAction->setCheckable(true);    connect(m_circleAction, &QAction::triggered, this, &MainWindow::drawCircle);    m_rectangleAction = new QAction("矩形", this);    m_rectangleAction->setCheckable(true);    connect(m_rectangleAction, &QAction::triggered, this, &MainWindow::drawRectangle);    m_polylineAction = new QAction("折线", this);    m_polylineAction->setCheckable(true);    connect(m_polylineAction, &QAction::triggered, this, &MainWindow::drawPolyline);    m_splineAction = new QAction("样条曲线", this);    m_splineAction->setCheckable(true);    connect(m_splineAction, &QAction::triggered, this, &MainWindow::drawSpline);    m_connectionAction = new QAction("连线", this);    m_connectionAction->setCheckable(true);    connect(m_connectionAction, &QAction::triggered, this, &MainWindow::drawConnection);    // 创建工具组,确保只有一个工具被选中    QActionGroup *toolGroup = new QActionGroup(this);    toolGroup->addAction(m_selectAction);    toolGroup->addAction(m_lineAction);    toolGroup->addAction(m_circleAction);    toolGroup->addAction(m_rectangleAction);    toolGroup->addAction(m_polylineAction);    toolGroup->addAction(m_splineAction);    toolGroup->addAction(m_connectionAction);    // 测量工具    m_measureDistanceAction = new QAction("测量距离", this);    connect(m_measureDistanceAction, &QAction::triggered, this, &MainWindow::measureDistance);    m_measureAngleAction = new QAction("测量角度", this);    connect(m_measureAngleAction, &QAction::triggered, this, &MainWindow::measureAngle);    m_measureAreaAction = new QAction("测量面积", this);    connect(m_measureAreaAction, &QAction::triggered, this, &MainWindow::measureArea);    // 视图操作    m_gridAction = new QAction("显示网格", this);    m_gridAction->setCheckable(true);    m_gridAction->setChecked(true);    connect(m_gridAction, &QAction::triggered, this, &MainWindow::toggleGrid);    m_snapAction = new QAction("对象捕捉", this);    m_snapAction->setCheckable(true);    m_snapAction->setChecked(true);    connect(m_snapAction, &QAction::triggered, this, &MainWindow::toggleSnap);    m_zoomInAction = new QAction("放大", this);    m_zoomInAction->setShortcut(QKeySequence::ZoomIn);    connect(m_zoomInAction, &QAction::triggered, this, &MainWindow::zoomIn);    m_zoomOutAction = new QAction("缩小", this);    m_zoomOutAction->setShortcut(QKeySequence::ZoomOut);    connect(m_zoomOutAction, &QAction::triggered, this, &MainWindow::zoomOut);    m_zoomFitAction = new QAction("适应窗口", this);    connect(m_zoomFitAction, &QAction::triggered, this, &MainWindow::zoomFit);    // 帮助    m_aboutAction = new QAction("关于(&A)", this);    connect(m_aboutAction, &QAction::triggered, this, &MainWindow::showAbout);}void MainWindow::createMenus(){    m_fileMenu = menuBar()->addMenu("文件(&F)");    m_fileMenu->addAction(m_newAction);    m_fileMenu->addAction(m_openAction);    m_fileMenu->addSeparator();    m_fileMenu->addAction(m_saveAction);    m_fileMenu->addAction(m_saveAsAction);    m_fileMenu->addSeparator();    m_fileMenu->addAction(m_exitAction);    m_editMenu = menuBar()->addMenu("编辑(&E)");    m_editMenu->addAction(m_undoAction);    m_editMenu->addAction(m_redoAction);    m_editMenu->addSeparator();    m_editMenu->addAction(m_deleteAction);    m_drawMenu = menuBar()->addMenu("绘图(&D)");    m_drawMenu->addAction(m_selectAction);    m_drawMenu->addSeparator();    m_drawMenu->addAction(m_lineAction);    m_drawMenu->addAction(m_circleAction);    m_drawMenu->addAction(m_rectangleAction);    m_drawMenu->addAction(m_polylineAction);    m_drawMenu->addAction(m_splineAction);    m_drawMenu->addAction(m_connectionAction);    m_toolsMenu = menuBar()->addMenu("工具(&T)");    m_toolsMenu->addAction(m_measureDistanceAction);    m_toolsMenu->addAction(m_measureAngleAction);    m_toolsMenu->addAction(m_measureAreaAction);    m_viewMenu = menuBar()->addMenu("视图(&V)");    m_viewMenu->addAction(m_gridAction);    m_viewMenu->addAction(m_snapAction);    m_viewMenu->addSeparator();    m_viewMenu->addAction(m_zoomInAction);    m_viewMenu->addAction(m_zoomOutAction);    m_viewMenu->addAction(m_zoomFitAction);    m_helpMenu = menuBar()->addMenu("帮助(&H)");    m_helpMenu->addAction(m_aboutAction);}void MainWindow::createToolBars(){    // 文件工具栏    m_fileToolBar = addToolBar("文件");    m_fileToolBar->addAction(m_newAction);    m_fileToolBar->addAction(m_openAction);    m_fileToolBar->addAction(m_saveAction);    // 编辑工具栏    m_editToolBar = addToolBar("编辑");    m_editToolBar->addAction(m_undoAction);    m_editToolBar->addAction(m_redoAction);    m_editToolBar->addAction(m_deleteAction);    // 绘图工具栏    m_drawToolBar = addToolBar("绘图工具");    m_drawToolBar->addAction(m_selectAction);    m_drawToolBar->addSeparator();    m_drawToolBar->addAction(m_lineAction);    m_drawToolBar->addAction(m_circleAction);    m_drawToolBar->addAction(m_rectangleAction);    m_drawToolBar->addAction(m_polylineAction);    m_drawToolBar->addAction(m_splineAction);    m_drawToolBar->addAction(m_connectionAction);    // 添加画笔宽度控制    m_drawToolBar->addSeparator();    m_drawToolBar->addWidget(new QLabel(" 线宽: "));    m_penWidthSpinBox = new QSpinBox();    m_penWidthSpinBox->setRange(1, 20);    m_penWidthSpinBox->setValue(1);    connect(m_penWidthSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),            this, &MainWindow::onPenWidthChanged);    m_drawToolBar->addWidget(m_penWidthSpinBox);    // 添加颜色选择按钮    QPushButton *penColorBtn = new QPushButton("画笔颜色");    connect(penColorBtn, &QPushButton::clicked, this, &MainWindow::onPenColorChanged);    m_drawToolBar->addWidget(penColorBtn);    QPushButton *brushColorBtn = new QPushButton("填充颜色");    connect(brushColorBtn, &QPushButton::clicked, this, &MainWindow::onBrushColorChanged);    m_drawToolBar->addWidget(brushColorBtn);    // 视图工具栏    m_viewToolBar = addToolBar("视图");    m_viewToolBar->addAction(m_gridAction);    m_viewToolBar->addAction(m_snapAction);    m_viewToolBar->addSeparator();    m_viewToolBar->addAction(m_zoomInAction);    m_viewToolBar->addAction(m_zoomOutAction);    m_viewToolBar->addAction(m_zoomFitAction);}void MainWindow::createDockWidgets(){    // 属性编辑器    QDockWidget *propertyDock = new QDockWidget("属性", this);    m_propertyEditor = new PropertyEditor(propertyDock);    propertyDock->setWidget(m_propertyEditor);    addDockWidget(Qt::RightDockWidgetArea, propertyDock);    connect(m_scene, &DrawingScene::selectionChanged,            m_propertyEditor, &PropertyEditor::onSelectionChanged);    connect(m_propertyEditor, &PropertyEditor::propertyChanged,            m_scene, &DrawingScene::onPropertyChanged);    // 组件库    QDockWidget *componentDock = new QDockWidget("组件库", this);    m_componentLibrary = new ComponentLibrary(componentDock);    componentDock->setWidget(m_componentLibrary);    addDockWidget(Qt::LeftDockWidgetArea, componentDock);    connect(m_componentLibrary, &ComponentLibrary::componentSelected,            m_scene, &DrawingScene::onComponentDropped);}void MainWindow::createStatusBar(){    statusBar()->showMessage("就绪");}void MainWindow::newFile(){    m_scene->clear();    m_currentFile.clear();    m_undoStack->clear();    setWindowTitle("工程制图软件 - 新建文件");    statusBar()->showMessage("新建文件", 2000);}void MainWindow::openFile(){    QString fileName = QFileDialog::getOpenFileName(this,        "打开文件", "", "工程图文件 (*.edw);;所有文件 (*.*)");    if(fileName.isEmpty())        return;    // 检查文件是否存在    QFile file(fileName);    if(!file.exists()) {        QMessageBox::warning(this, "错误", QString("文件不存在:\n%1").arg(fileName));        return;    }    FileManager fileManager;    if(fileManager.loadFromFile(fileName, m_scene, m_layerManager)) {        m_currentFile = fileName;        setWindowTitle(QString("工程制图软件 - %1").arg(fileName));        statusBar()->showMessage("文件已打开", 2000);    } else {        QMessageBox::warning(this, "错误", QString("无法打开文件:\n%1\n\n可能的原因:\n1. 文件格式不正确\n2. 文件已损坏\n3. 没有读取权限").arg(fileName));    }}void MainWindow::saveFile(){    if(m_currentFile.isEmpty()) {        saveFileAs();    } else {        FileManager fileManager;        if(fileManager.saveToFile(m_currentFile, m_scene, m_layerManager)) {            statusBar()->showMessage("文件已保存", 2000);        } else {            QMessageBox::warning(this, "错误", "无法保存文件");        }    }}void MainWindow::saveFileAs(){    QString fileName = QFileDialog::getSaveFileName(this,        "保存文件", "", "工程图文件 (*.edw);;所有文件 (*.*)");    if(fileName.isEmpty())        return;    FileManager fileManager;    if(fileManager.saveToFile(fileName, m_scene, m_layerManager)) {        m_currentFile = fileName;        setWindowTitle(QString("工程制图软件 - %1").arg(fileName));        statusBar()->showMessage("文件已保存", 2000);    } else {        QMessageBox::warning(this, "错误", "无法保存文件");    }}void MainWindow::undo(){    m_undoStack->undo();}void MainWindow::redo(){    m_undoStack->redo();}void MainWindow::drawLine(){    m_scene->setDrawMode(DrawingScene::DrawLine);    statusBar()->showMessage("绘制直线:点击起点和终点");}void MainWindow::drawCircle(){    m_scene->setDrawMode(DrawingScene::DrawCircle);    statusBar()->showMessage("绘制圆:点击中心点,然后拖动设置半径");}void MainWindow::drawRectangle(){    m_scene->setDrawMode(DrawingScene::DrawRectangle);    statusBar()->showMessage("绘制矩形:点击起点,然后拖动到对角点");}void MainWindow::drawPolyline(){    m_scene->setDrawMode(DrawingScene::DrawPolyline);    statusBar()->showMessage("绘制折线:依次点击各个顶点,双击结束");}void MainWindow::drawSpline(){    m_scene->setDrawMode(DrawingScene::DrawSpline);    statusBar()->showMessage("绘制样条曲线:依次点击控制点,双击结束");}void MainWindow::drawConnection(){    m_scene->setDrawMode(DrawingScene::DrawConnection);    statusBar()->showMessage("连线模式:从起始图形按下拖拽到目标图形并释放完成连接");}void MainWindow::selectMode(){    m_scene->setDrawMode(DrawingScene::SelectMode);    statusBar()->showMessage("选择模式");}void MainWindow::deleteSelected(){    m_scene->deleteSelectedShapes();    statusBar()->showMessage("已删除选中的图形", 2000);}void MainWindow::measureDistance(){    MeasureTool::measureDistance(m_scene, this);}void MainWindow::measureAngle(){    MeasureTool::measureAngle(m_scene, this);}void MainWindow::measureArea(){    MeasureTool::measureArea(m_scene, this);}void MainWindow::toggleGrid(){    m_gridManager->setVisible(m_gridAction->isChecked());    m_view->viewport()->update();}void MainWindow::toggleSnap(){    m_snapManager->setEnabled(m_snapAction->isChecked());}void MainWindow::zoomIn(){    m_view->scale(1.2, 1.2);}void MainWindow::zoomOut(){    m_view->scale(1.0 / 1.2, 1.0 / 1.2);}void MainWindow::zoomFit(){    m_view->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);}void MainWindow::showAbout(){    QMessageBox::about(this, "关于",        "工程制图软件 v1.0\n\n"        "基于Qt 6.5开发的专业工程制图软件\n"        "支持多种图形绘制、图层管理、对象捕捉等功能");}void MainWindow::onPenWidthChanged(int width){    m_scene->setCurrentPenWidth(width);}void MainWindow::onPenColorChanged(){    QColor color = QColorDialog::getColor(Qt::black, this, "选择画笔颜色");    if(color.isValid()) {        m_scene->setCurrentPenColor(color);    }}void MainWindow::onBrushColorChanged(){    QColor color = QColorDialog::getColor(Qt::white, this, "选择填充颜色");    if(color.isValid()) {        m_scene->setCurrentBrushColor(color);    }}void MainWindow::closeEvent(QCloseEvent *event){    // 检查场景中是否有对象    if(m_scene->items().isEmpty()) {        // 没有对象,直接关闭        event->accept();        return;    }    // 有对象,提示用户保存    QMessageBox::StandardButton reply = QMessageBox::warning(this,        "确认关闭",        "绘制区域有图形对象,是否保存文件?",        QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);    if(reply == QMessageBox::Save) {        saveFile();        event->accept();    } else if (reply == QMessageBox::Discard) {        event->accept();    } else {        event->ignore();    }}
希望这篇文章能为您的Linux C/C++、Qt开发等学习之旅提供有价值的参考!感谢各位关注👉【Qt开发宝典】微信公众号,获取更多技术干货。