在CodeBolcks下wxSmith的C++编程教程——在屏幕上绘图和保存绘图

news/2025/9/26 0:07:57/文章来源:https://www.cnblogs.com/lexyao/p/19112367

0.前言

 欢迎来到 wxSmith 教程页面!wxSmith 与 Code::Blocks、wxWidgets 和 C++ 编译器相结合,为您提供一种所见即所得的方式来创建具有图形用户界面 (GUI) 的应用程序。该组合形成了一个用于快速应用程序开发 (RAD) 的工具,可在 Linux、Mac OS X 和 Windows 上运行。当您工作时,您会在屏幕上看到您正在设计的表单;他们看着你,就像他们看着你的程序的用户一样。

这些教程假设您是Code::Blocks 或 wxWidgets 的初学者,事实上,它们也是学习它们的好教程;假设您对 C++ 有基本的了解,您能够看懂教程中的C++实例代码。
这套教程的其他文章可以从以下文章中找到:

在CodeBolcks下wxSmith的C++编程教程——wxSmith教程目录(序言) - lexyao - 博客园

编写这篇文章参照了Code::Blocks 用户文档中wxSmith教程的以下文章:

WxSmith tutorial: Drawing on the Screen and Saving Drawings - Code::Blocks

在这篇文章中你将看到以下内容:

  1. 关于在屏幕上绘图和保存绘图
  2. 在屏幕上绘图
  3. 将图片另存为 PNG 和 JPEG 文件
  4. 可展开的图
  5. 结束语

1.关于在屏幕上绘图和保存绘图

上一篇教程中我们讲述了基础的绘制图形的操作,在这一篇教程中我们将讲解更多的图形绘制知识。

在本教程中,我们将在屏幕上绘制如下图,并将其保存为.jpg和.png文件。

RedSquare

 或许这篇教程的英文版(Code::Blocks 用户文档中wxSmith教程)的作者是俄罗斯人,他把图片中的方块解释为俄罗斯元素,而第二行的西里尔文字“Красная площадь”的意思是红场(莫斯科红场)。我在图片中添加了一行中文,哈哈哈。其实,图片中有什么不重要,重要的是我们以此为例讲述绘图的方法。

在 wxWidgets 中,人们总是在某种设备上下文上绘制一个图形。从使用 wxWidgets 的程序员的角度来看,设备上下文是一个黑匣子,它使我们不必知道如何将图形发送到打印机、屏幕、位图和.jpg文件的详细信息。完全相同的代码创建用于所有三个输出设备的图形。让我用示意图代码来说明我们的例子。

像往常一样,我们将从一个空应用程序开始,项目名称为tu08。在项目的主窗口中添加三个按钮,这篇教程中绘制图形的操作将通过点击这三个按钮启动。
构建并运行项目,确保项目能够正常构建、运行。运行后看到的主窗口如下图所示:

wechat_2025-09-25_214428_793 

2.在屏幕上绘图

为了在屏幕上显示图表,我们需要一个框架中的面板,因此在 Code::Blocks 主菜单上单击 wxSmith 项并选择“添加 wxFrame”。当窗口出现询问类名并建议“NewFrame”时,让我们将其命名为“PictureFrame”(只要是合法的名字就行,你也可以用其他的合法的名字)。接受建议的其他默认值,然后完成添加框架。

在进一步讨论之前,我们必须修复当用户尝试关闭此框架时会发生什么。双击PictureFrame,此时将显示与框架关联的 C++ 代码。在文件底部,您应该会看到以下行:

    void PictureFrame::OnClose(wxCloseEvent& event){}

我们希望当用户尝试关闭 PictureFrame 窗口时不能关闭主窗口。如果我们像以前一样将 Close() 命令放入大括号之间的正文中,则关闭此窗口将关闭整个应用程序。相反,我们放置 Destroy(),它会清除当前窗口,但不会关闭整个程序。所以我们应该有:

    void PictureFrame::OnClose(wxCloseEvent& event){Destroy();}

现在回到编辑区(单击 C++ 代码上方栏中的 PictureFrame.wxs),在PictureFrame 上放置一个 wxBoxSizer,并在 wxBoxSizer中放置一个wxPanel面板。我们将在此面板绘制图片以在屏幕上查看。在属性浏览器中,选中其“Expand”框,取消选中“默认大小”,然后将“宽度”填写为 310,“高度”填写为 210。(准备画一个 300 X 200 的矩形,所以这给了他在边缘周围有一点额外的空间。

现在,我们需要为此面板的 Paint 事件添加一些代码。因此,单击面板,单击属性浏览器上方的 {},找到EVT_PAINT(它应该在列表的顶部),单击它,然后单击行右边缘的向下箭头,然后选择添加新处理程序。接受建议的名称,然后单击确定。

您会发现自己回到了PictureFrame.cpp,并显示了以下用于编写代码来处理此事件的框架:

void PictureFrame::OnPanel1Paint(wxPaintEvent& event)
{
}

我们只需要在框架中间添加两行,如下所示:

void PictureFrame::OnPanel1Paint(wxPaintEvent& event)
{wxPaintDC dc( Panel1 );Repin(dc);
}

上面代码中有一个名为Repin的函数,这是我们给绘制图形的函数取的名字。以下是函数Repin的代码,将这些代码复制到PictureFrame.cpp文件中PictureFrame::OnPanel1Paint之前:

void Repin(wxDC &dc)
{// 将设备上下文清除为全白dc.SetBrush(*wxWHITE_BRUSH);dc.Clear();// 创建一个宽5像素的蓝色画笔用于绘制边框。wxColor Blue(0, 0, 255);wxPen myBluePen(Blue, 10, wxSOLID);// 告诉dc使用它
    dc.SetPen(myBluePen);// 用蓝色边框绘制一个矩形,矩形的内部用当前画刷填充,当前画刷是白色dc.DrawRectangle(0, 0, 300, 200);// 设置画刷和画笔为红色dc.SetBrush(*wxRED_BRUSH);dc.SetPen(*wxRED_PEN);// 绘制高和宽都是40像素的矩形,它的左上角坐标为10,10dc.DrawRectangle(10, 10, 40, 40);// 创建一支宽3像素的绿色画笔,用于绘制一条实线wxPen myGreenPen(*wxGREEN, 3, wxSOLID);// 告诉dc开始用这支笔画画。
    dc.SetPen(myGreenPen);// 画一条水平线dc.DrawLine(55, 40, 290, 40);// 将文本前景设置为黑色dc.SetTextForeground(*wxBLACK);// 用默认的字体、字号绘制一些文字dc.DrawText(wxT("Красная площадь"), 50, 60);dc.DrawText(wxT("我爱北京天安门"), 50, 90);// 创建一个16磅的字体,既不粗体, 也不斜体,无下划线。wxFont BigFont(16, wxFONTFAMILY_ROMAN, wxNORMAL, wxNORMAL, false);// 告诉dc使用这个字体
    dc.SetFont(BigFont);// 写下我们图片的标题。dc.DrawText(wxT("Red Square"), 60, 10);
}

至此我们已经完成了PictureFrame 绘制图形的程序设计,下面我们将添加代码在主窗口中通过点击按钮“Show”将PictureFrame 显示出来。为此,单击代码编辑器上方行中的 tu08Frame.wxs以返回主窗口,双击“Show”按钮为其添加事件响应函数,并添加以下代码(在tu08frame.cpp中):

void tu08Frame::OnButton1Click(wxCommandEvent& event)
{PictureFrame* frm = new PictureFrame(this);frm->Show();
}

在tu08frame.cpp中包含头文件PictureFrame.h:

#include "PictureFrame.h"

最后,我们构建并运行的程序,在应用程序的主界面点击“Show”按钮,将会看到PictureFrame运行后的画面,说明Repin能够正常工作了。

wechat_2025-09-25_231430_095

 你会发现,每点击Show按钮一次就会打开一个PictureFrame窗口。你可以关闭PictureFrame窗口;关闭主窗口时还没有关闭的PictureFrame窗口也会一同关闭。

3.将图片另存为 PNG 和 JPEG 文件

我们希望运行时单击“Save”按钮时绘图保存为 PNG 和 JPEG 文件,需要为响应Save按钮的点击事件添加代码。

要将我们的绘图保存到文件中,我们需要做以下工作:

  1. 首先创建一个位图,
  2. 然后创建一个内存设备上下文(DC),
  3. 接着将位图交给内存DC用作绘画的纸张,
  4. 然后让Repin在上面绘图,
  5. 最后从DC中释放位图,并将其写入为文件。 

在编辑器中双击“Save”按钮,在按钮的事件响应函数中添加以下代码:

void tu08Frame::OnButton2Click(wxCommandEvent& event)
{// 创建一个宽 300 像素,高 200 像素的位图。// 称之为“纸”,因为我们将在上面书写。wxBitmap *paper = new wxBitmap(300, 200);// 创建一个内存设备上下文
    wxMemoryDC memDC;// 告诉memDC在“纸上”写。memDC.SelectObject(*paper);// 调用Repin函数在memDC上画我们的图像
    Repin(memDC);// 告诉 memDC 在一个虚假的位图上写入;// 这释放了“纸张”,以便它可以将自己写入文件。
    memDC.SelectObject(wxNullBitmap);// 将“纸”中的内容放入一个png和一个jpeg文件中。paper->SaveFile(_T("RedSquare.png"), wxBITMAP_TYPE_PNG, (wxPalette*)NULL);paper->SaveFile(_T("RedSquare.jpg"), wxBITMAP_TYPE_JPEG, (wxPalette*)NULL);delete paper;
}

构建并运行应用程序,单击Save按钮,然后打开应用程序tu08.exe所在的文件夹,你会看到两个图形文件。

wechat_2025-09-25_234116_190

 打开这两个文件,你会看到里面正是我们使用Repin绘制的图像。

(为了成功编译上述内容,您需要添加一个函数原型,以便 Repin() 在tu08Main.cpp中可见。在 PictureFrame.h 的末尾,在结束标头保护之前添加行 void Repin(wxDC &dc); 。)

4.可展开的图

当我们运行时单击“Show”按钮打开PictureFrame窗口,我们可以拖动改变窗口的大小,但绘图的大小不受影响。
让我们为 Stretch 按钮添加事件响应代码,并绘制一个图形,当用户调整显示它的框的大小时,它确实会改变大小和比例。该图将是一个红色矩形,带有固定宽度的绿色边框。

和创建PictureFrame时一样,在 Code::Blocks 主菜单上,选择 wxSmith >>Add wxFrame;接受框架的建议名称,即 NewFrame。使用 Destroy() 填充 OnClose 代码框。在框架上,放一个盒子尺寸;在尺寸管理器中放置一个面板,在属性浏览器中将面板设置为 200 宽和 200 高。请务选中“Expand”属性。通过单击 {} 图标将属性浏览器更改为事件浏览器,找到 Paint 事件,单击行右侧的下拉箭头,然后选择“Add new handler”。在显示的代码框中,添加代码以获取以下内容:

void NewFrame::OnPanel1Paint(wxPaintEvent& event)
{wxPaintDC dc( Panel1 );dc.SetPen( wxPen( *wxGREEN, 5 ) ); // 绿色的笔宽5像素dc.SetBrush(*wxRED_BRUSH);// 获取窗口尺寸wxSize sz = GetClientSize();// 我们的矩形尺寸wxCoord w = sz.x/2 , h = sz.y/2;// 将矩形居中在窗口上,但不要在负位置绘制。int x = wxMax(0, (sz.x - w)/2);int y = wxMax(0, (sz.y - h)/2);wxRect rectToDraw(x, y, w, h);dc.DrawRectangle(rectToDraw);
}

此代码引入了几个新的 wxWidgets 结构:wxSize、wxCoord、wxRect 和 wxMax 函数。从名称和此处的使用方式中可以清楚地看出它们的含义。当然,C++ 函数 GetClientSize() 是使绘图大小取决于绘制窗口大小的关键。

现在回到主窗口的代码中,在顶部添加 #include“NewFrame.h”行。然后让 wxSmith 给你标有“Stretch”的按钮的代码框架。在该代码框架中添加行以使整体如下所示:

void tu08Frame::OnButton3Click(wxCommandEvent& event)
{NewFrame* ffrm = new NewFrame(this);ffrm->Show();}

构建并运行应用程序。单击“Stretch”按钮。您应该得到带有绿色边框的红色矩形的图片。现在尝试更改窗口的大小,矩形应该按比例放大或缩小。

wechat_2025-09-26_000200_118 

5.结束语

在这篇教程中,我们讲述了更多的绘制图形的方法,文字也是一种图形。
要了解更多的图形绘制的方法,可以通过多看多练达到自己的目的。

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

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

相关文章

怎么用网站做chm中国电子政务网站建设意见

概述 在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适。 很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等)。 在Java项目中调用第三方接口…

苍穹外卖-day07(缓存菜品,缓存套餐,添加购物车,查看购物车,清空购物车) - a

苍穹外卖-day07(缓存菜品,缓存套餐,添加购物车,查看购物车,清空购物车) 课程内容缓存菜品 缓存套餐 添加购物车 查看购物车 清空购物车功能实现:缓存商品、购物车 效果图:1. 缓存菜品 1.1 问题说明 用户端小程…

一次CPU飙升问题排查定位

操作流程CPU飙升问题定位:定位高CPU进程 进程内高CPU线程 top -Hp [PID] jstack [PID] grep -A 20 [十六进制TID]抓取线程栈/arthas工具attach进程后profiler生成火焰图 2.排查常见原因 代码逻辑问题:死循环、递归爆…

ros2 control 2

controller 创建一个pkg,在pkg中新建一个controller.yaml。点击查看代码 controller_manager:ros__parameters:update_rate: 50joint_state_broadcaster:type: joint_state_broadcaster/JointStateBroadcasterdiff_dr…

基于洞察的智能编程法——从直觉到代码的原型炼成术

本文基于分析心理学的知识,介绍一种针对 Ni 主导人格设计的高效 AI 编程工具使用方式,旨在将 Ni 主导者对系统演化路径的深层洞察转化为可规模化、可验证、高效落地的技术产出。基于洞察的智能编程法——从直觉到代码…

lc1036-逃离大迷宫

难度:困难题目描述原题示例 输入:blocked = [[0,1],[1,0]], source = [0,0], target = [0,2] 输出:false输入:blocked = [], source = [0,0], target = [999999,999999] 输出:true题解思路:bfs golang 写得不好,…

做后期哪个网站素材好博纳网络科技有限公司

函数是将具有独立功能的代码块组成一个整体,使其具有特殊功能的代码集。它将复杂的算法过程分解为若干个小任务,隐藏相关细节,使得程序结构更加清晰,易于维护。通过接收输入参数完成一段算法指令,输出或存储相关结果。…

防城港网站seo免费申请网站 主机 空间

软件架构之计算机网络 第 4 章 计算机网络4.1 网络架构与协议4.1.1 网络互联模型4.1.2 常见的网络协议4.1.3 IPv6 4.2 局域网与广域网4.2.2 无线局域网4.2.3 广域网技术4.2.4 网络接入技术 4.3 网络互连与常用设备4.4 网络工程4.4.1 网络规划4.4.2 网络设计4.4.3 网络实施 4.5 …

9.25学习笔记

环境速览( 节点 新装组件 端口 备注 node1 Hive3.1.3 + MySQL 8.0 + Spark3.5.0 3306/10000/8080 HiveServer2 WebUI node2 Spark HistoryServer 18080 日志持久化到 HDFS node3 Kafka 3.7.0 + ZooKeeper(复用) 9092 …

新学期每日总结(第4天)

相较昨日复习了Java知识

wordpress 邮箱 通知成都网站优化哪家好

多维时序 | MATLAB实现BiTCN-selfAttention自注意力机制结合双向时间卷积神经网络多变量时间序列预测 目录 多维时序 | MATLAB实现BiTCN-selfAttention自注意力机制结合双向时间卷积神经网络多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.M…

外贸长尾关键词挖掘网站关键词排名点击软件网站

目录 前言 1、文件目录 2、安装依赖 3、POM项目实战-案例:打开指定页面 目录结构: pages中的代码: cases中的代码: 4、解决登录问题 问题: 解决方案: 获取登录的用户信息(cookie&a…

网站怎么做边框网页版微信会留下记录吗

【判断题】在竞争激烈的市场环境中,职业生的就业优势是证书【简答题】请把今天的语文作业拍照、语音上传,谢谢!【简答题】请把今天的语文作业拍照上传,今日古诗语音上传,谢谢!【简答题】请把今天的作业拍照、语音上传,谢谢!【判断题】职业纵向发展只体现在技术和职务提升。【判…

VSCode 升级 C++支持版本

下载最新版本mingw:https://github.com/niXman/mingw-builds-binaries/releases 解压,覆盖原mingw路径 修改vscode c++插件配置 执行gcc -v -E -x c++ - 添加 starts here后的路径到系统include path中 指定C/C++版本…

太原模板建站定制网站爱站网工具包

软件架构是任何软件项目成功的关键。良好的架构不仅能够支撑软件的功能实现,还能确保其性能、可维护性、可扩展性和安全性。在软件工程领域,经过多年的研究和实践,已经总结出了许多宝贵的原则和模式,用以指导软件架构的设计。以下…

怎样将自己做的网站给别人看制作网架厂家

一、ubuntu下安装docker 1、命令行终端内直接输入docker 可以看到安装docker的命令提示 2、安装需要注意的几个点 (1)需要管理员权限 (2)更新软件源后再进行安装 命令行输入命令 sudo apt-get update #更新软件源 sudo apt install docker.io #安装docker 如图所示 二…

25.9.25

学习了MyBatis的基础知识,配置环境,明天跟敲代码,加速

网站如何做那种诱导广告珠海企业网站建设价格

题主的意思,搭建的自动化测试框架要包括API测试,UI测试,APP测试三类。以上三类其实可以简化为两类,那就是: 1)接口自动化测试框架搭建 2)UI自动化测试框架搭建。 没问题,安排&#x…

在electron-vite使用ShadCN

集成tailwind 这一步较为简单,仅需按照官网步骤即可~ 这里不再赘述! 稍微需要注意的是,你的集成配置都需要在 electron.vite.config.ts! 补全tsconfig.json{// ..."compilerOptions": {"composite&q…

苏州企业门户网站工信部域名备案管理系统

文章目录 概要整体架构流程 概要 把公共的部分单独拆出来&#xff0c;封装到一个新的vue文件夹中&#xff0c; 里面的数据通过父传子的方式传递&#xff0c;子通过props接受&#xff08;静态代码实现的树状图细看代码展示&#xff09; 整体架构流程 <template><!-- …