欢迎来到 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: Working with multiple resources - Code::Blocks
在这篇文章中你将看到以下内容:
- 使用多个窗口
- 以模式使用对话框窗口
- 使用无模式对话框和帧窗口
- 结束语
1.使用多个窗口
1.1 本教程演示的内容及准备工作
在本教程中,我将向您展示如何创建具有多个窗口的应用程序。像往常一样,我们的应用程序将有一个wxFrame 窗口作为主窗口;在wxFrame 中显示一个按钮,单击按钮创建一个 wxDialog 窗口。这两个窗口之间的一个重要区别是打开wxDialog 窗口后应用程序中的所有其他窗口都将冻结,直到它关闭。这种做法通常用于向用户询问一个或多个问题,这些问题需要在下一步的工作进行之前得到答案。
像往常一样,我们将从一个空项目开始。让我们将项目命名为tu04(原版教程中项目名称为“Tutorial_4”)。与往常一样,检查空应用程序是否正常编译、运行和关闭。
1.2 在项目中添加新的窗口
在创建tu04的时候向导已经给我们添加了一个基于wxFrame 的窗口,现在我们给项目添加第二个窗口。
可以从 Code::Blocks 主菜单的 wxSmith 菜单项添加新窗口。您可以在那里找到以下可能性:
- 添加 wxPanel - 这将在窗口中添加一个新面板
- 添加 wxFloatingFrame – 这将添加浮动框架窗口
- 添加 wxDialog - 这将添加一个新的对话框窗口
- 添加 wxFrame - 这将添加一个新的框架窗口。
让我们首先添加一个新的 wxDialog。选择此选项时,您将看到以下窗口:
在这里我们可以设置以下参数:
- 类名称(Class name) —— 将为资源生成的类的名称。它也将是资源的名称
- 头文件(Head file) —— 带有类声明的头文件的名称
- 源文件(Source file) —— 具有类定义的源文件的名称
- XRC 文件(XRC file) —— 如果选中此选项,您可以输入将包含 XRC 结构的 XRC 文件的名称(XRC 文件将在尚未编写的教程中介绍。
- 将 XRC 文件添加到自动加载列表(Add XRC file to autoload list) —— 此选项仅适用于 XRC 文件,并通知 wxSmith 在应用程序启动时应自动加载 XRC 文件。
现在让我们将窗口的名称更改为更独特的名称,例如“FirstDialog”。请注意,如果更改类名,则文件名也会更新。(更准确地说,只要您不手动更改它们,它们就会更新)。
单击“确定”后,系统将提示您输入将添加新窗口的构建目标列表。同时选择调试和发布,我们可以继续。
编辑器中会自动打开一个新对话框。在编辑器框架的顶部栏中,请注意,编辑器可以使用两个 .wxs 文件,即 tu04Frame.wxs 和新创建的 FirstDialog1.wxs。两者都是完全空白的。在 FirstDialog.wxs 中,让我们添加一些简单的内容,使其在编辑器中如下所示:
从这个图中弄清楚已经完成了什么是一个很好的复习练习。这与我们在上一个教程开始时所做的非常相似。在进一步阅读之前,请尝试亲手制作。(说实话,你输入什么并不重要,因为我们要做的只是展示它,但如果你需要复习,这是我所做的:
- 在编辑器上放一个 wxBoxSizer。
- 在尺寸调整器中放置一个 wxPanel(并记住打开其 Expand 属性)。
- 在面板上放置一个 wxStaticBoxSizer,将其方向更改为 Vertical,并将其标签设置为“这是第一个对话框”。
- 在 StaticBoxSizer 中,首先放置一个 wxTextCtrl,然后放置一个 wxStaticText 项。
此时,编辑器最右侧的“显示预览”按钮将向我们显示我们拥有的内容,而运行程序将不显示任何内容,因为应用程序没有编程来显示我们的对话框。
现在让我们回到 Code::Blocks 菜单上的 wxSmith 项,添加一个 wxFrame 窗口 (FirstFrame) 并在其中添加一些内容:
同样,让窗口看起来像这样是一个很好的复习,但内容对接下来的内容并不重要。
2.以模式使用对话框窗口
对话框(但不是框架)可以模态显示。当对话框以模式显示时,应用程序中的所有其他窗口都将冻结,直到对话框完成其工作。当用户必须在继续后续工作之前提供一些信息时,模式对话框非常有用。例如,用于配置新资源的窗口以模态方式显示。
现在让我们尝试调用我们的对话。通常,此类对话框会弹出以响应某些用户操作,例如选择菜单选项或单击按钮。我们将使用一个按钮,因为这种方法非常简单。让我们切换到主框架 —— 创建新项目后立即打开的框架 —— 并添加一个框尺寸调整器和按钮:
现在,我们必须为按钮单击事件创建一个作。最简单的方法是双击编辑器中的按钮。wxSmith 会自动添加一个新的事件处理函数:
void tu04Frame::OnButton1Click(wxCommandEvent& event) { }
如果您没有看到此代码,请向下滚动到.cpp文件的末尾。在.cpp文件中点击键盘上的任何一个箭头,编辑区会快速显示出上面的内容所在的位置。
在此框架中,让我们放置调用对话框的代码:
void tu04Frame::OnButton1Click(wxCommandEvent& event) {FirstDialog dialog(this);dialog.ShowModal(); }
在添加的第一行中,我们创建对话框的对象,并声明this窗口(主框架)是对话框的父级。在第二行中,我们以模态方式显示对话框。对 ShowModal() 的调用是对话框的一个函数(或方法),它会阻止其他所有内容,直到对话框关闭。
在应用程序编译之前,我们还需要添加一件事。跳转到文件的开头,并在第一组其他包含项后添加以下代码:
#include "FirstDialog.h"
请注意,您不应该将其添加到如下所示的代码中:
//(*InternalHeaders(tu04Frame) #include <wx/intl.h> #include <wx/string.h> //*)
这是 wxSmith 自动生成的代码块。每个块都以 //(*BlockName 注释开头,以 //* 结尾)。您可能会在头文件和源文件中找到其他类似的块。如果您更改其内容,则下次在编辑器中更改某些内容时,所有更改都将丢失。这些评论及其中的所有内容都属于 wxSmith,所以不要乱搞它们。
总而言之,标题部分应该如下所示:
#include "wx_pch.h" #include "tu04Main.h" #include <wx/msgdlg.h> #include "FirstDialog.h"//(*InternalHeaders(tu04Frame) #include <wx/intl.h> #include <wx/string.h> //*)
现在我们可以编译和运行我们的应用程序。如果单击主窗口上的按钮,将弹出此对话框:
3.使用无模式对话框和帧窗口
显示窗口的另一种方法是作为无模式窗口。在这种情况下,新窗口不会阻止应用程序中的其他窗口,并且两个(或多个)窗口可以在一个应用程序中协作。在将新代码添加到应用程序之前,您还应该了解一件事。每个窗口只能在其对象(资源的 C++ 类的实例)存在时存在。因此,我们不能使用与模式对话相同的方法。在模式模式下,对象是通过简单的声明语句创建的作为事件处理程序的局部变量的:
FirstDialog dialog(this);
我们之所以能这样做,只是因为只要显示对话框,ShowModal 方法就会阻塞。现在,对于没有 ShowModal 可能性的 wxFrame,我们将不得不使用 C++ 的 new 运算符创建对象,因为对象在离开处理程序函数后必须存在,并且因为不使用模态模式的窗口将在窗口关闭时自动删除此类对象。
为了允许创建 FirstFrame 类,我们应该将 #include “FirstFrame.h” 添加到包含列表中,就像 FirstDialog 一样:
#include "wx_pch.h" #include "tu04Main.h" #include <wx/msgdlg.h> #include "FirstDialog.h" #include "FirstFrame.h"//(*InternalHeaders(tu04Frame) #include <wx/intl.h> #include <wx/string.h> //*)
现在让我们在主框架中再添加两个按钮:
- Add new dialog
- Add new frame
我们还可以命名第一个按钮以显示它的作用:
现在让我们向“Add new dialog”对话框按钮添加一个处理程序:
void tu04Frame::OnButton2Click(wxCommandEvent& event) {FirstDialog* dlg = new FirstDialog(this);dlg->Show(); }
类似地,我们可以为 FirstFrame 编写代码:
void tu04Frame::OnButton3Click(wxCommandEvent& event) {FirstFrame* frm = new FirstFrame(this);frm->Show(); }
现在,每次我们单击“Add new dialog”或“Add new frame”按钮时,都会出现一个新窗口。当然,你也可以点击第一个按钮对比三个按钮点击后的差别。
4.结束语
除了最基础的应用,一般情况下应用程序都会有多个窗口。在这篇文章中我们讲解了构建多窗口应用程序的方法。在这里我们在窗口中添加的内容仅仅是为了演示,没有实际的意义。将来在你自己设计的程序中可以根据你的需要添加更多有用的功能。
应用程序运行后的第一个窗口是主窗口,主窗口关闭则结束应用程序的运行。在主窗口之后打开的任何应用程序可以关闭自己或者被主窗口中的操作关闭,不会因为他的关闭结束应用程序的运行。
后续打开的窗口可以是模式窗口或非模式窗口,至于选择哪一种,你可以根据自己的需要选择合适的模式。