简易CAD程序:Qt多文档程序的一种实现

注:文中所列代码质量不高,但不影响演示我的思路

实现思路说明

  1. 实现DemoApplication
    相当于MFC中CWinAppEx的派生类,暂时没加什么功能。
    DemoApplication.h

    #pragma once#include <QtWidgets/QApplication>//相当于MFC中CWinAppEx的派生类,
    class DemoApplication : public QApplication
    {Q_OBJECTpublic:DemoApplication(int &argc, char **argv);~DemoApplication();};
    

    DemoApplication.cpp

    #include "DemoApplication.h"DemoApplication::DemoApplication(int &argc, char **argv): QApplication(argc, argv)
    {
    }DemoApplication::~DemoApplication()
    {
    }
  2. 实现DemoDocument
    相当与MFC的CDocument。DemoDocument保存了当前所有视图的指针(此处实际是DeomChildWindow*,因为DeomChildWindow与DeomView时1对1关系,根据DeomChildWindow可以获得DemoView指针,简化设计,就这样处理了),实现了增加视图addView、移除视图removeView、获取视图数量getViewCount等函数。
    DemoDocument.h

    #pragma once#include <QObject>
    #include <list>class DemoChildWindow;//相当与MFC的CDocument
    class DemoDocument : public QObject
    {Q_OBJECTpublic:DemoDocument(QObject *parent = 0);~DemoDocument();void addView(DemoChildWindow* pChildWindow);void removeView(DemoChildWindow* pChildWindow);int getViewCount() const;unsigned int getId() { return m_nId; }signals:void closedDocument(DemoDocument* pDocument);private:static unsigned int allocId();private:static unsigned int s_NextId;unsigned int m_nId = 0;std::list<DemoChildWindow*> m_viewList; //视图列表
    };

    DemoDocument.cpp

    #include "DemoDocument.h"unsigned int DemoDocument::s_NextId = 0;DemoDocument::DemoDocument(QObject *parent): QObject(parent)
    {m_nId = allocId();
    }DemoDocument::~DemoDocument()
    {
    }unsigned int DemoDocument::allocId()
    {if (DemoDocument::s_NextId == std::numeric_limits<unsigned int>::max()){DemoDocument::s_NextId = 0;}return ++DemoDocument::s_NextId;
    }void DemoDocument::addView(DemoChildWindow* pChildWindow)
    {m_viewList.push_back(pChildWindow);
    }void DemoDocument::removeView(DemoChildWindow* pChildWindow)
    {auto it = std::find(m_viewList.begin(), m_viewList.end(), pChildWindow);if (it != m_viewList.end() ){m_viewList.erase(it);}if (m_viewList.size() == 0){emit closedDocument(this);}
    }int DemoDocument::getViewCount() const
    {return int(m_viewList.size());
    }
  3. 实现DemoMainWindow
    相当于MFC中的CMainFrame,派生自CMDIFrameWndEx。此类new了一个QMdiArea对象,通过此对象实现多文档程序的通用功能,如切换窗口、层叠窗口、平铺窗口等。类DemoMainWindow直接管理了所有打开的文档,这点同MFC不一样,MFC是通过文档管理器、文档模版处理的,此处简化下,直接在DemoMainWindow中管理。此处我让DemoMainWindow负责新建、打开、关闭文档。
    DemoMainWindow.h

    #pragma once#include <QtWidgets/QMainWindow>
    #include <QMdiArea>
    #include <list>
    #include <memory>class DemoDocument;//相当于MFC中的CMainFrame,派生自CMDIFrameWndEx
    class DemoMainWindow : public QMainWindow
    {Q_OBJECTpublic:DemoMainWindow(QWidget *parent = Q_NULLPTR);virtual ~DemoMainWindow();DemoDocument* getActiveDocument() const;protected slots:void onSlotNewDocument();void onSlotClosedDocument(DemoDocument* pDocument );void onSlotNewWindow();private://创建文档的一个视图(DemoChildWindow-DeomView)void createNewWindow(DemoDocument* pDocument );private:QMdiArea* m_pMDIArea = nullptr;std::list<DemoDocument*> m_DocList; //文档列表
    };

    DemoMainWindow.cpp

    #include "DemoMainWindow.h"
    #include "DemoDocument.h"
    #include "DemoChildWindow.h"#include <QMdiSubWindow>
    #include <QMenuBar>DemoMainWindow::DemoMainWindow(QWidget *parent): QMainWindow(parent)
    {m_pMDIArea = new QMdiArea();this->setCentralWidget(m_pMDIArea);//void subWindowActivated(QMdiSubWindow * window)//菜单QMenu* pFileMenu = menuBar()->addMenu(QStringLiteral("文件"));QAction* pNewDocAction = new QAction(QStringLiteral("新建"), this);connect(pNewDocAction, SIGNAL(triggered()), this, SLOT(onSlotNewDocument()));pFileMenu->addAction(pNewDocAction);//窗口(实际需要动态添加到菜单栏中,即有视图窗口打开,就加入,否则就移除,此处暂未实现)QMenu* pWinMenu = menuBar()->addMenu(QStringLiteral("窗口"));QAction* pNewWinAction = new QAction(QStringLiteral("新建"), this);connect(pNewWinAction, SIGNAL(triggered()), this, SLOT(onSlotNewWindow()));pWinMenu->addAction(pNewWinAction);}DemoMainWindow::~DemoMainWindow()
    {for (auto pDoc : m_DocList){delete pDoc;}m_DocList.clear();
    }void DemoMainWindow::onSlotNewDocument()
    {auto pNewDoc = new DemoDocument();m_DocList.push_back(pNewDoc);createNewWindow(pNewDoc);connect(pNewDoc, SIGNAL(closedDocument(DemoDocument*)), this, SLOT(onSlotClosedDocument(DemoDocument*)));
    }void DemoMainWindow::onSlotClosedDocument(DemoDocument* pDocument)
    {auto it = std::find(m_DocList.begin(), m_DocList.end(), pDocument);if (it != m_DocList.end()){auto pDoc = *it;delete pDoc;m_DocList.erase(it);}
    }void DemoMainWindow::onSlotNewWindow()
    {auto pDocument = getActiveDocument();createNewWindow(pDocument);
    }//创建文档的一个视图(DemoChildWindow-DeomView)
    void DemoMainWindow::createNewWindow(DemoDocument* pDocument)
    {if (!pDocument){Q_ASSERT(false);return;}auto pChildWnd = new DemoChildWindow(pDocument);//自己new QMdiSubWindow时,必须设置Qt::WA_DeleteOnClose,参看文档//When you create your own subwindow, you must set the Qt::WA_DeleteOnClose widget //attribute if you want the window to be deleted when closed in the MDI area. //If not, the window will be hidden and the MDI area will not activate the next subwindow.//添加方式如下:
    //	QMdiSubWindow *pMdiSubWindow = new QMdiSubWindow;
    //	pMdiSubWindow->setWidget(pChildWnd);
    //	pMdiSubWindow->setAttribute(Qt::WA_DeleteOnClose);
    //	m_pMDIArea->addSubWindow(pMdiSubWindow);
    //	pMdiSubWindow->show();//这中方法更简单auto pMdiSubWindow = m_pMDIArea->addSubWindow(pChildWnd);pMdiSubWindow->setWindowTitle(QStringLiteral("文档%1:%2").arg(pDocument->getId()).arg(pDocument->getViewCount()));pMdiSubWindow->show();
    }DemoDocument* DemoMainWindow::getActiveDocument() const
    {auto pCurMdiSubWindow = m_pMDIArea->currentSubWindow();if (!pCurMdiSubWindow){return nullptr;}auto pChildWnd = dynamic_cast<DemoChildWindow*>(pCurMdiSubWindow->widget());if (!pChildWnd){Q_ASSERT(false);return nullptr;}return pChildWnd->GetDocument();
    }
  4. 实现DemoChildWindow
    相当于MFC中的ChildFrm,派生自CMDIChildWndEx, 与文档是n-1关系, 与DemoView时1-1关系。此类负责创建DemoView,并且包含了文档对象的指针。MFC中创建ChildFrm以及CView没那么直接,通过消息触发创建了CView,具体参看MFC即可,我此处就简化处理创建的过程。
    DemoChildWindow.h

    #pragma once#include <QWidget>class DemoDocument;
    class DemoView;//相当于MFC中的ChildFrm,派生自CMDIChildWndEx, 与文档是n-1关系, 与DemoView时1-1关系,
    class DemoChildWindow : public QWidget
    {Q_OBJECTpublic:DemoChildWindow(DemoDocument* pDoc, QWidget* parent = 0, Qt::WindowFlags f = 0);~DemoChildWindow();DemoDocument* GetDocument() const;protected:virtual void closeEvent(QCloseEvent * event) override;private:DemoDocument* m_pDoc;DemoView* m_pView;
    };

    DemoChildWindow.cpp

    #include "DemoChildWindow.h"
    #include "DemoView.h"
    #include "DemoDocument.h"
    #include <QVBoxLayout>DemoChildWindow::DemoChildWindow(DemoDocument* pDoc, QWidget *parent, Qt::WindowFlags flags): QWidget(parent, flags)
    {m_pDoc = pDoc;m_pView = new DemoView();m_pDoc->addView(this);auto pVBoxLayout = new QVBoxLayout();pVBoxLayout->addWidget(m_pView);this->setLayout(pVBoxLayout);
    }DemoChildWindow::~DemoChildWindow()
    {
    }DemoDocument* DemoChildWindow::GetDocument() const
    {return m_pDoc;
    }void DemoChildWindow::closeEvent(QCloseEvent * event)
    {m_pDoc->removeView(this);return QWidget::closeEvent(event);
    }
    
  5. 实现DemoView
    相当与MFC中的CView,在DemoView中仅显示了硬编码的文本字符串。
    DemoView.h

    #pragma once#include <QWidget>//相当与MFC中的CView
    class DemoView : public QWidget
    {Q_OBJECTpublic:DemoView(QWidget *parent = Q_NULLPTR);~DemoView();private://Ui::DemoView ui;
    };

    DemoView.cpp

    #include "DemoView.h"
    #include <QVBoxLayout>
    #include <QLabel>DemoView::DemoView(QWidget *parent): QWidget(parent)
    {auto pVBoxLayout = new QVBoxLayout();pVBoxLayout->addWidget(new QLabel(QStringLiteral("视图测试")));this->setLayout(pVBoxLayout);this->setMinimumSize(300, 200);
    }DemoView::~DemoView()
    {
    }
  6. main函数

    #include "DemoApplication.h"
    #include "DemoMainWindow.h"int main(int argc, char *argv[])
    {DemoApplication a(argc, argv);DemoMainWindow w;w.show();return a.exec();
    }

运行演示

在这里插入图片描述

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

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

相关文章

以太坊(3)——智能合约

智能合约 首先明确一下几个说法&#xff08;说法不严谨&#xff0c;为了介绍清晰才说的&#xff09;&#xff1a; 全节点矿工 节点账户 智能合约是基于Solidity语言编写的 学习Solidity语言可以到WFT学院官网&#xff08;Hello from WTF Academy | WTF Academy&#xff09;…

以x为界,分隔链表为两个分区,各分区内元素相对位置不变

题目描述&#xff1a; 题目思路&#xff1a; 1.设置两个头指针表示两个分区&#xff0c;并对每个分区设置相对于的遍历指针&#xff0c;指向分区链表链尾 2.设置原链表的遍历指针&#xff0c;判断指针所指元素是否小于目标值x&#xff0c;小于的话将结点添加到第一个分区末尾…

搭建电商电子商务平台有哪些好用的电商API数据采集接口?

电商API接口主要用于帮助开发者将电商功能集成到自己的应用程序中&#xff0c;实现诸如商品检索、商品价格数据获取、订单处理、支付、物流跟踪等功能。以下是一些常用的电商API接口提供商&#xff1a; 主流电商平台API&#xff1a; 淘宝开放平台&#xff1a;提供淘宝、天猫、…

ngnix 入门 二,docker启动nginx, 安装ssl 证书,使用配置文件,映射后端服务 ,提供给前端项目访问

搭建生产环境真不是人做的事&#xff0c;特别是对于一知半解的人。仅以此文献给各位技术人 说一下背景&#xff1a;项目前后端分离&#xff0c;前端 vue3 、小程序端 &#xff0c;后端 go 提供服务。 微信小程序需要使用 https 请求。 这就必须让我们想到nginx 了 想要达到的…

MySQL学习之DQL语句(数据查询语言)

准备SQL CREATE TABLE student ( id int, -- 编号 name varchar(20), -- 姓名 age int, -- 年龄 sex varchar(5), -- 性别 address varchar(100), -- 地址 math int, -- 数学 english int -- 英语 );INSERT INTO student(id,NAME,age,sex,address,math,english) VALUES (1,…

【UE5.1 角色练习】02-添加慢走、快速跑、蹲伏功能

目录 前言 步骤 一、慢走 二、快速跑 三、蹲伏 前言 在上一篇文章基础上&#xff08;【UE5.1 角色练习】01-使用小白人蓝图控制商城角色移动&#xff09;继续实现角色的慢走、快速跑以及蹲伏功能 步骤 一、慢走 1. 打开项目设置&#xff0c;添加一个操作映射&#x…

思维导图-VPN

浏览器集成了受信任的机构的证书

linux---信号的捕捉和处理

提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、信号 可以简单理解为信号是一个进程给另一个信号发消息&#xff0c;进程收到对应的信号就执行对应的方法&#xff0c;linux信号可以分为实时信号和非实时信号 1-31为非实时信号&#xff0c;34-64为…

计算机精选期刊特辑

文章目录 一、征稿简介二、合作期刊三、投稿咨询四、咨询 一、征稿简介 艾思科蓝依托互联网信息与数据库技术、整合渠道与合作资源&#xff0c;提供EI/SCI/SCIE/SSCI期刊论文的内容审查、发表支持等服务。艾思科蓝与多所知名出版社达成战略合作关系&#xff0c;持续开展合作征…

利用神经网络学习语言(一)——自然语言处理的基本要素

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch10_rnn/tokenizer.ipynb 本系列文章将深入探讨一种应用广泛的神经…

syncthing文件夹同步与版本管理

1 前言 syncthing可以用来同步文件夹里的所有文件&#xff0c;并且有不错的版本管理&#xff0c;基本每次更改文件&#xff0c;20-40秒就被扫描到了&#xff0c;非常丝滑&#xff1b;这次以此来同步obsidian的插件和文件&#xff0c;达到多端同步&#xff1b; 我家里有一台台…

Android HAL到Framework

一、为什么需要Framwork? Framework实际上是⼀个应⽤程序的框架&#xff0c;提供了很多服务&#xff1a; 1、丰富⽽⼜可扩展的视图&#xff08;Views&#xff09;&#xff0c; 可以⽤来构建应⽤程序&#xff0c;它包括列表&#xff08;lists&#xff09;&#xff0c;⽹格&am…

闲话 .NET(4):为什么要跨平台?

前言 .NET Core 有一个关键词就是跨平台&#xff0c;为什么要跨平台呢&#xff1f;Windows 操作系统不香吗&#xff1f;今天我们来聊聊这个 原因一&#xff1a;安全考虑 Windows OS 是闭源的&#xff0c;而 Linux 是开源的&#xff0c;因此有些公司的技术负责人就认为 Linux…

如何将老板的游戏机接入阿里云自建K8S跑大模型(下)- 安装nvidia/gpu-operator支持GPU在容器中共享

文章目录 安装nvidia/gpu-operator支持GPU在容器中共享 安装nvidia/gpu-operator支持GPU在容器中共享 安装 nvidia/gpu-operator遇到两个问题&#xff1a; 由于我们都懂的某个原因&#xff0c;导致某些镜像一直现在不成功。 解决办法&#xff0c;准备一个&#x1fa9c;&#…

车间人员作业行为智能检测 AI视觉在生产车间制造中的应用

车间人员作业行为智能检测系统基于神经网络人工智能视觉算法&#xff0c;车间人员作业行为智能检测通过对车间监控摄像头获取的视频图像进行分析和识别&#xff0c;实现了对人员操作行为的智能检测。系统对工人的操作环节进行分解&#xff0c;根据时间、动作标准等方面制定了规…

MemoryDB 2024 论文分享

论文地址点这里。 TL;DR MemoryDB 通过底层依赖 AWS 内部系统 Multi-AZ Transaction Log 实现了 11 个 9 的持久性保证。 通过依赖 Transaction Log 的 Condition API 和租约机制来实现了一致性和可用性保证。 通过周期性调度 Off-box 节点来外部 Rewrite binlog 避免了内存…

C语言基础——循环(2)+关机程序

欢迎点赞支持 个人主页&#xff1a;励志不掉头发的内向程序员&#xff1b; 专栏主页&#xff1a;C语言基础&#xff1b; 文章目录 目录 前言 一、for循环的补充 二、循环的嵌套 1、嵌套的介绍 1.1 练习&#xff1a; 题目解析&#xff1a; 优化&#xff1a; 三、goto语句 1、go…

3DEXPERIENCE DELMIA Role: RFP - Fabrication Robot Programmer

Discipline: Robotics Role: RFP - Fabrication Robot Programmer 在虚拟工厂中定义、验证和编程机器人弧焊和密封剂沉积系统 模拟和验证完整的焊接、密封剂沉积和搬运机器人系统&#xff0c;以消除代价高昂的碰撞并优化生产率提供精确的生产就绪型机器人程序&#xff0c;同…

Day 38 防火墙技术IPtables

一&#xff1a;防火墙简介 1.简介 ​ iptables其实并不是真正的防火墙&#xff0c;我们可以把他理解为一个客户端的代理&#xff0c;用户是通过iptables这个代理&#xff0c;将用户的安全设定执行到对应的“安全框架”中&#xff0c;这个“安全框架”才是真正的防火墙。这个框…

mac安装Redis

官网&#xff1a; https://redis.io中文网&#xff1a; Redis中文网 安装 brew install redis 查看版本 redis-server --version 开启关闭服务 方式一&#xff08;不推荐&#xff09; 这种方式不太建议&#xff0c;因为控制台不用输出相应的日志 开启服务 brew service…