MFC案例:基于对话框的简易阅读器

news2024/12/13 16:16:17

一、功能目标:
  1.阅读txt文件
  2.阅读时可以调整字体及字的大小
  3.打开曾经阅读过的文件时,能够自动从上次阅读结束的位置开始显示,也就是能够保存和再次使用阅读信息。
  4.对于利用剪贴板粘贴来的文字能够存储成txt文件保存。
  5.显示界面可以调整大小。
二、设计步骤
  1. 建立一个基于对话框的MFC项目,项目名:simpleReader
  1.1 对话框左上角图标Icon改为自己的图标
     步骤:右键资源视图Icon->选择添加资源->导入自己的图标->回到资源视图->删除ID为IDR_MAINFRAME的Icon->右键新导入Icon ID->选择属性,ID号改为IDR_MAINFRAME;
  2.从工具箱中向对话框内拖入一个文本编辑框(Edit Control)。
  2.1 让编辑框充满对话框,这个编辑框是显示阅读文字的界面。
  2.2 右键编辑框,点击属性,将编辑框的ID改为IDC_TEXTEDIT。同时,对编辑框的其它属性进行设置:Auto VScroll置为True,垂直滚动置为True,多行置为True,想要返回置为True。
  2.3 右键文本编辑框,选择添加变量,变量名:m_textEdit,注意是控件类型。
  3.在CsimpleReaderDlg类中以public方式声明需要的变量
      具体位置可在simpleReaderDlg.h文件最后(在自动生成的变量m_textEdit的后边)。
  3.1 声明 CString filePathName; //阅读文件的路径及文件名
  3.2 声明自定义类readFileInfo,用于记录阅读文件的相关信息
     typedef class
     {
     public:
         CString fileName; //已阅读文件名(含路径)
         int startPos; //阅读位置
         int endPos; //阅读位置
      } readFileInfo;
      //说明:阅读位置使用阅读结束时光标所在位置(字符数)表示。这个位置实质是光标选黑的区域,因此表示其位置需有两个数表示。通过编辑框对象的成员函数GetSel()函数获得,该函数的返回值是DWORD类型,通过LOWORD、HIWORD两个有参宏将返回值解析得到两个阅读位置。当没有选择区域只是光标停在某位置时,这两个值相等。
  3.3 #define READNUM 4 //定义记录阅读文件个数的常量(可更改),打开文件个数超过READNUM时,最早打开的文件会被顶掉。
  3.4 声明readFileInfo数组:
    readFileInfo readfileinfo[READNUM]; //用于记录最多READNUM个文件阅读信息的自定义类数组
  3.5 #define MAXTCHAR 10000  //文本编辑框接收数组最大长度
  4. 阅读信息存储文件
  4.1 前面声明了自定义数组readfileinfo[READNUM]用来处理阅读信息,这些信息如不保存进文件,程序关闭时信息会丢失,因此有必要建立一个文件进行保存,文件名:readInfo.txt,保存路径就在项目目录中。
  4.2 在simpleReaderDlg.h文件中,类内以public方式声明阅读信息保存函数:readInfoSave(); 在文件simpleReaderDlg.cpp中实现这个函数。代码如下:

void CsimpleReaderDlg::readInfoSave()
{
  CFile file;
  file.Open(L"readInfo.txt", CFile::modeCreate | CFile::modeWrite);
  for (int i = 0; i < READNUM; i++)
  {
	TCHAR a[256] = { 0 };
	wcscpy_s(a, readfileinfo[i].fileName);
	TCHAR b[64] = { 0 };
	TCHAR c[64] = { 0 };
	wsprintf(b, L"%i\0", readfileinfo[i].startPos);
	wsprintf(c, L"%i\0", readfileinfo[i].endPos);
	file.Write(a, 256);
	file.Write(b, 64);
	file.Write(c, 64);
  }
  file.Close();
}

  4.3 在simpleReaderDlg.h文件中,类内以public方式声明阅读信息读取函数:readInfoRead(); 并在simpleReaderDlg.cpp中实现这个函数。代码如下:

void CsimpleReaderDlg::readInfoRead()
{
  CFile file;
  if (file.Open(L"readInfo.txt", CFile::modeRead))//打开成功
  {
	TCHAR a[258] = { 0 };
	TCHAR b[64] = { 0 };
	TCHAR c[64] = { 0 };
	for (int i = 0; i < READNUM; i++)
	{
  	  file.Read(a, 256);
	  file.Read(b, 64);
	  file.Read(c, 64);
	  readfileinfo[i].fileName = a;
	  readfileinfo[i].startPos = _wtoi(b);
	  readfileinfo[i].endPos = _wtoi(c);
	}
	file.Close();
  } else
  {
    MessageBox(L"调试");
    return;
  }
}

  4.4 在simpleReaderDlg.cpp中,找到OnInitDialog()函数,在里面添加一些代码。目的是,当程序第一次运行,保存阅读文件信息的文件readInfo.txt不存在时,添加一个记录内容为空的文件保存成readInfo.txt。具体在TODO:后面添加下列代码:

  CFile fileCheck;
  if (!fileCheck.Open(L"readInfo.txt", CFile::modeRead))
  {
     fileCheck.Open(L"readInfo.txt", CFile::modeCreate | 
        CFile::modeWrite); //如不存在,新建一个
     for (int i = 0; i < READNUM; i++) //填入空数据
     {
	readfileinfo[i].fileName = L"";
	readfileinfo[i].startPos = 0;
	readfileinfo[i].endPos = 0;
     }
     fileCheck.Close();
     readInfoSave(); //保存文件
  }
  else fileCheck.Close(); //如存在,结束检查
  readInfoRead(); //读入数据存进数组readfileinfo[READNUM]

  5.退出函数
  5.1 对话框右上角“X”单击响应退出函数
   右键对话框->属性->单击消息列->选中消息 WM_CLOSE->点击<Add>OnClose。这样,在simpleReaderDlg.cpp中添加了void CsimpleReaderDlg::OnClose()函数,这个函数是点击对话框右上角“X”的响应函数,这个系统自动生成的函数在函数尾部自动调用了父类关闭函数CDialogEx::OnClose()。我们在此只需处理保存阅读文件信息即可,其余交给CDialogEx::OnClose()处理,代码如下:

void CsimpleReaderDlg::OnClose()
{
  int m_startPos = LOWORD(m_textEdit.GetSel()); 
  int m_endPos = HIWORD(m_textEdit.GetSel());
    //m_textEdit.GetSel()的返回值是DWORD类型,其低位、高位有不同含义。
    //低位代表选择区域的开始位置、高位代表选择区域的结束位置。将光标
    //置于某处不做选择,高低位值相等,用此位置表示阅读位置。
  readFileInfo temp;
  temp.fileName = filePathName;
  temp.startPos = m_startPos;
  temp.endPos = m_endPos;
  int choice = -1; 
    //choice用来表示当前阅读文件是否读过以及相关信息在readfileinfo数组
    //中的位置,-1表示没有读过,数组中没有它的信息
  for (int i = 0; i < READNUM; i++) //确定choice的值
  {
    if (readfileinfo[i].fileName == filePathName) choice = i;
   }
  if (choice == -1) //当前阅读文件信息不在readfileinfo数组中
  {
    for (int i = READNUM - 1; i > 0; i--) //将数组第0位置腾出
    {
      readfileinfo[i] = readfileinfo[i - 1];
     }
   }
  if (choice > 0 && choice < READNUM) 
   /*当前阅读文件信息在readfileinfo数组1~READNUM-1之间,需将其移动
     到数组第0位置,实际是空出0位,后边重新写入*/
   {
     for (int i = choice; i > 0; i--)
     {
	readfileinfo[i] = readfileinfo[i - 1];
      }
    }
  //choice==0的情况无需调整,故不考虑
  readfileinfo[0] = temp; //将当前阅读文件信息存入数组第0位置
  readInfoSave(); //将readfileinfo数组存入文件readInfo.txt

  5.1 选择菜单退出
    见后。
  6. 在对话框上添加菜单栏
   步骤:解决方案资源管理器->右键项目名simpleReader->添加->资源->选择Meni->新建->进入菜单编辑界面->顶行写上“文件(F)”。这时,回到资源视图,点击Menu,可看到菜单(指整个菜单)的ID是IDR_MENU1。右键对话框->属性->菜单->选中这个ID。
  6.1 打开文件函数 
  再回到菜单编辑界面,在“文件(F)”的下方添加菜单“打开(O)”,接着,右键“打开(O)”选择属性,将其ID改为ID_OPEN;再次右键“打开(O)”,选择“添加事件处理程序”进入事件处理程序设置界面:类列表选择CsimpleReaderDlg,其余按缺省,确定后在simpleReaderDlg.cpp可看到空的函数void CsimpleReaderDlg::OnOpen(),相关代码如下:

void CsimpleReaderDlg::OnOpen()
{
  CFileDialog dlg ( //打开文件对话框
    TRUE, NULL, NULL, 
    OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
    L"All Files(*.TXT)|*.TXT||", AfxGetMainWnd());
    CString tempText = _T("");
    if (dlg.DoModal() == IDOK)
    {
      filePathName = dlg.GetPathName();
      CFile file(filePathName, CFile::modeRead);
      TCHAR* read = new TCHAR[MAXTCHAR];
      memset(read, '\0', sizeof(TCHAR) * MAXTCHAR);
      file.Read(read, MAXTCHAR);
      for (int i = 0;; i++)
      {
	 tempText += read[i];
	 if (read[i] == '\0')break;
       }
      file.Close();
      m_textEdit.SetWindowText(tempText);
     }
    int choice = -1; //检查当前打开文件是否已阅读过
    for (int i = 0; i < READNUM; i++) //
    {
      if (readfileinfo[i].fileName == filePathName) choice = i;
     }
    int a, b;
    if (choice == -1)
    {
      a = 0; b = 0; //如果是未阅读读过的阅读位置设在开始
     }
    else 
    {
	a = readfileinfo[choice].startPos;
	b = readfileinfo[choice].endPos;
     }
     m_textEdit.SetSel(a,b,0);
}

  6.2 从菜单退出函数
   回到菜单编辑界面,在“打开(O)”下面填写“退出(Q)”,右键“退出”->属性->ID改为ID_QUIT;再右键“退出”,选择“添加事件处理程序”进入事件处理程序设置界面:类列表选择CsimpleReaderDlg,其余按缺省,确定后在simpleReaderDlg.cpp可看到空的函数void CsimpleReaderDlg::OnQuit(),有关处理文件退出代码如下,就一句:

void CsimpleReaderDlg::OnQuit()
{
  // TODO: 在此添加命令处理程序代码
  OnClose();//这里只需调用点击右上角“X”的响应函数即可
}

  6.3 字体调整函数
  回到菜单编辑界面,在“文件(F)”右边再在添加一列下拉函数“格式(O)”,在“格式”下面填写“字体(F)”,右键“字体”->属性->ID改为ID_FONT;再右键“字体”,选择“添加事件处理程序”进入事件处理程序设置界面:类列表选择CsimpleReaderDlg,其余按缺省,确定后在simpleReaderDlg.cpp可看到空的函数void CsimpleReaderDlg::OnFont()。在写代码前,在CsimpleReaderDlg.h类内先声明一个CFont对象m_Font,用于保存新选定的字体。具体代码如下:

void CsimpleReaderDlg::OnFont()
{
	// TODO: 在此添加命令处理程序代码
	//记录阅读位置
	int m_startPos = LOWORD(m_textEdit.GetSel());
	int m_endPos = HIWORD(m_textEdit.GetSel());
	//设置字体
	CFont* tempFont = m_textEdit.GetFont(); //获取编辑框当前字体指针
	LOGFONT LogFont; //声明逻辑字体对象
	tempFont->GetLogFont(&LogFont); //加载逻辑字体
	CFontDialog dlg(&LogFont);  //逻辑字体对话框,在此选择字体
	if (dlg.DoModal() == IDOK)
	{
		m_Font.Detach();  //将m_Font与原对象剥离
		LOGFONT temp;
		dlg.GetCurrentFont(&temp);   //获取当前字体信息
		m_Font.CreateFontIndirect(&temp); //创建字体
		m_textEdit.SetFont(&m_Font);  //设置字体
	}
	//重置阅读位置
	m_textEdit.SetSel(m_startPos, m_endPos, 0);
}

  7.处理文本框内容变动函数
  单击文本编辑框->右键选择属性->点击控件事件->点击EN_CHANGE->选择
<add>OnEnChangeTextedit,在cpp文件中可以看到增加了void CsimpleReaderDlg::OnEnChangeTextedit()这个文件。添加这个文件的目的是当采用Crt_V方式粘贴进阅读内容时,对粘贴的内容予以保存。相关代码如下:

void CsimpleReaderDlg::OnEnChangeTextedit()
{
  // TODO:  如果该控件是 RICHEDIT 控件,它将不
  // 发送此通知,除非重写 CDialogEx::OnInitDialog()
  // 函数并调用 CRichEditCtrl().SetEventMask(),
  // 同时将 ENM_CHANGE 标志“或”运算到掩码中。

  // TODO:  在此添加控件通知处理程序代码
  CString writeText;
  m_textEdit.GetWindowText(writeText);
  TCHAR* write = new TCHAR[MAXTCHAR]; //在堆区声明一个一百万字节的字符串数组
  memset(write, '\0', sizeof(TCHAR) * MAXTCHAR);
  write = writeText.GetBuffer();
  CFileDialog dlg(  //保存文件对话框
		FALSE, NULL, NULL, OFN_HIDEREADONLY | 
                OFN_OVERWRITEPROMPT,
		_T("All Files(*.TXT)|*.TXT||"), AfxGetMainWnd()); 
  if (dlg.DoModal() == IDOK) //判断另存为确认键是否按下
  {
     filePathName = dlg.GetPathName();
	//获取路径及文件名并赋给全局变量,除此处使用外退出时也需使用
     if ((filePathName.Right(4) != _T(".TXT")) && (filePathName.Right(4) != _T(".txt")))
     {
	filePathName += _T(".TXT"); //如无后缀则添加
      }
     CFile file(filePathName, CFile::modeCreate | CFile::modeWrite);
     file.Write(write, writeText.GetLength() * sizeof(write[0]));
     file.Close();
   }
}

  9.处理对话框大小变动函数
  选中对话框,右键属性->单击消息->选择WM_SIZE消息->点击<add>OnSize,这样在.cpp文件中,多了一个函数void CsimpleReaderDlg::OnSize(UINT nType, int cx, int cy),在这个函数中TODO:行后边添加:

	CWnd* pEdit = GetDlgItem(IDC_TEXTEDIT);
	if (pEdit) pEdit->MoveWindow(0, 0, cx, cy);

10.帮助文件
  选择菜单编辑界面,在“格式”右边在添加一列下拉:“帮助(H)”。在“帮助”下边填上“使用说明(N)”,右键“使用说明”选择属性,将ID改为ID_NOTE;接着,再右键使用说明,选择添加事件处理程序。这样,在.cpp中生成函数void CsimpleReaderDlg::OnNote()。先不写代码,在资源视图中:右键项目名->添加->资源->Dialog->新建;在对话框界面,将“取消”按钮删除。再拖入两个静态文本框,将其ID改为IDC_NOTE、IDC_NOTE1。
  右键对话框,添加MFC类,类名FileHelp,基类CDialogEx,对话框ID使用默认IDD_DIALOG1。然后在 simpleReaderDlg.cpp首部添加:#include “Filehelp.h”。再在解决方案资源管理器中找到HelpFile.cpp,点开,在void HelpFile::DoDataExchange(CDataExchange* pDX)函数的CDialogEx::DoDataExchange(pDX)行下面添加下列代码:

	CFont font,font1;
	font.CreateFont(20, 20, 0, 0, FW_NORMAL, FALSE, FALSE,
		FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		FIXED_PITCH | FF_MODERN, _T("楷体") );

	GetDlgItem(IDC_NOTE)->SetFont(&font);
	CString strText;
	strText = L"使用方法:";
	GetDlgItem(IDC_NOTE)->SetWindowText(strText);
	font1.CreateFont(18, 0, 0, 0, FW_NORMAL, FALSE, TRUE,
		TRUE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		FIXED_PITCH | FF_MODERN, _T("楷体"));
	strText = L"1.一次最好只打开一个文件,只有关闭程序时阅读位置信息才被保存。";
    GetDlgItem(IDC_NOTE1)->SetWindowText(strText);
	strText = "2.若调整界面窗口大小可以在打开文件前进行,以免文字跑动。";
	GetDlgItem(IDC_NOTE2)->SetWindowText(strText);
	strText = "3.阅读期间改变字体、字号等操作对原文件不起作用。";
	GetDlgItem(IDC_NOTE3)->SetWindowText(strText);
	strText = "4.本简易阅读器的字符集是UTF-16,如打开某些文件显示乱码,可用其它软件打开文件然后Ctr_C、Ctr_V到本阅读器,保存一下再打开。";
	GetDlgItem(IDC_NOTE4)->SetWindowText(strText);

前面生成的OnNote()函数的代码如下:

void CsimpleReaderDlg::OnNote()
{
	// TODO: 在此添加命令处理程序代码
	HelpFile dlg;
	dlg.DoModal();//创建模态对话框
}

程序完成后的界面截图如下:

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

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

相关文章

【开源】基于SpringBoot框架的个性化的旅游网站 (计算机毕业设计)+万字毕业论文 T025

系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 操作系统…

谷粒商城—分布式基础

1. 整体介绍 1)安装vagrant 2)安装Centos7 $ vagrant init centos/7 A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on…

MySQL概述以及下载安装

MySQL5.7概述以及下载安装&#xff08;centOS7&#xff09; 一、MySQL简介 MySQL是一个典型的关系数据库&#xff0c;目前是Oracle公司产品之一&#xff0c;也是目前主流使用的关系型数据库之一。使用MySQL可以进行最基本的数据存储、管理、查询等操作&#xff0c;也可以方便的…

中粮凤凰里共有产权看房记

中粮凤凰里看房是希望而来&#xff0c;失望而归。主要是对如下失望&#xff0c;下述仅个人看房感受&#xff1a; 1. 户型不喜欢&#xff1a;三房的厨房和餐厅位置很奇葩 2. 样板间在25楼&#xff1a;湖景一言难尽和有工厂噪声 3. 精装修的交房质量:阳台的推拉门用料很草率 …

轮播(css+js)

目录 1.实现效果 2.基础代码演示 2.1js代码 2.1css样式 2.3实现效果 3.实现点击切换 3.1给button添加点击事件 3.2效果图如下 3.3发现问题 3.3.1不循环 3.3.2循环 1.实现效果 2.基础代码演示 2.1js代码 <div class"out-box"><div class"tes…

深度学习(2)前向传播与反向传播

这一次我们重点讲解前向传播与反向传播&#xff0c;对这里还是有点糊涂 前向传播&#xff08;Forward Propagation&#xff09;和反向传播&#xff08;Backward Propagation&#xff09;是深度学习中神经网络训练的核心过程。它们分别负责计算神经网络的输出以及更新神经网络的…

HTML5 拖拽 API 深度解析

一、HTML5 拖拽 API 深度解析 1.1 背景与发展 HTML5 的拖拽 API 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算&#xff0c;而 HTML5 提供了标准化的拖拽事件和数据传递机制&#xff0c;使得开发者能够快速实现从一个元素拖拽到另一个元素的交互…

前端自己也能开启HTTPS

目录 前言 使用mkcert 安装 创建证书 利用 mkcert 创建 ca 根据 ca 创建 cert 安装证书 项目开启HTTPS 安装插件 配置 vitecofnig.js 最终效果 前言 今天我发现了一个宝藏&#xff0c;兄弟们&#xff01;就是前端开发阶段是可以使用https来开发的。对不懂前端的后端兄…

精通 Python 网络安全

与 FTP、SSH 和 SNMP 服务器交互 本章将帮助您了解允许我们与 FTP、SSH 和 SNMP 服务器交互的模块。在本章中&#xff0c;我们将探讨网络中的计算机如何相互交互。一些允许我们连接 FTP、SSH 和 SNMP 服务器的工具可以在 Python 中找到&#xff0c;其中我们可以突出显示 FTPLi…

【C++跬步积累】 —— 二叉搜索树(模拟实现+源代码)

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;C跬步积累 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日一题 &#x1f7e1; Linux跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0…

Redis安装和Python练习(Windows11 + Python3.X + Pycharm社区版)

环境 Windows11 Python3.X Pycharm社区版 思路 1 github下载redis压缩包 &#xff0c;安装并启动redis服务&#xff0c;在客户端连接redis服务。 2 在pycharm中运行python程序&#xff0c;连接redis服务&#xff0c;熟悉redis的使用和巩固python语言。 3 python开发环境…

【电子通识】能用5V电源去驱动线圈电压12V的继电器吗?

最近新人在使用继电器做一些工装&#xff0c;选择的是一款汽车级的继电器JZC-32F/012-ZS3(555) 。其原因主要是因为封装小&#xff0c;通流能力也OK。 但因为产品是5V USB-TypeC接口供电的&#xff0c;所以他想用5V电源去驱动继电器&#xff0c;从而减少一个电源输入或是电源升…

先进电机拓扑及控制算法介绍(2)——开绕组电机拓扑的容错控制

1.引言 共直流母线开绕组电机拓扑通过打开绕组中性点&#xff0c;电机绕组可由单逆变器供电改为双逆变器供电&#xff0c;这可以将电机的调速范围扩大为原来的两倍&#xff08;考虑到三次谐波反电势的因素&#xff0c;最低也可以把转速扩大为原来的根号3倍&#xff09;。扩大转…

️️️ 避坑指南:如何修复国密gmssl 库填充问题并提炼优秀加密实践20241212

&#x1f6e1;️ 避坑指南&#xff1a;如何修复国密gmssl 库填充问题并提炼优秀加密实践 ✨ 引言 在当下的数据安全环境中&#xff0c;SM4作为中国国家密码算法的代表性选择&#xff0c;被广泛应用于金融、通信和政府领域。然而&#xff0c;在实际开发中&#xff0c;即便是开…

C++ webrtc开发(非原生开发,linux上使用libdatachannel库)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、libdatachannel库的下载和build二、开始使用 1.2.引入库3.开始使用 总结 前言 使用c开发webrtc在互联网上留下的资料甚少&#xff0c;经过我一段时间的探…

【工具】linux matlab 的使用

问题1 - 复制图表 在使用linux matlab画图后&#xff0c;无法保存figure。 例如在windows下 但是在linux下并没有这个“Copy Figure”的选项。 这是因为 “ The Copy Figure option is not available on Linux systems. Use the programmatic alternative.” 解决方案&…

系统思考—本质

“执行力不足&#xff0c;真的是问题的根本吗&#xff1f;” 最近我和不少企业创办人交流时&#xff0c;大家普遍提到“执行力”的问题&#xff0c;但我发现&#xff0c;背后其实隐藏着更深层次的原因。当我用系统思考的视角深入拆解时&#xff0c;执行力不足&#xff0c;未必…

模方如何置平处理模型表面?

(1) 点击“多边形绘制“后在编辑模型视图中通过绘制多边形对 OBJ 进行编辑&#xff0c;将立面进行置平处理 选择需要表面置平的范围 (2) 点击“置平“即可看到效果

AAAI 2025 camera ready提交注意事项

您必须在截止日期前填写、签署并返回 AAAI 版权表&#xff08;除非 AAAI Press 指示使用 AAAI 分发许可证&#xff09;。 您必须根据作者的格式说明阅读并格式化您的论文和 PDF。 您必须使用我们的电子提交表格准时提交您的电子文件和摘要。 您必须向 AAAI Press 支付任何所需的…

QT核心功能概览

QT的学习&#xff08;一&#xff09;如何查阅QT文档&#xff1f;&#xff08;以QPushButton为例&#xff09;_qt的组件在qt文档那里面看-CSDN博客 QPushButton Class | Qt Widgets 5.15.18 一、前言 QT虽说功能很庞大&#xff0c;但是常用的控件也不是很多&#xff0c;也就只…