Code::Blocks(以下简称CB)丑是丑了点,但功能强大,开源免费,用wxWidgets构建的。
个人感觉名字起得不好,但个人感觉归个人感觉,Nobody Cares!
前面我们已经学习了在Windows平台上开发wxWidgets应用,但我们的代码是手写的。我们也注意到,即使一个简单的图形用户界面(GUI,graphical user interface)我们也不得不写若干行代码。
因此,我们不禁会想:我们能对此做些什么?(老实说,我没想过,我喜欢手写代码)GUI代码自动生成怎么样?听起来相当有趣!CB还真有一个插件,叫作wxSmith,能够在一个可视化编辑器内,基于用户生成的GUI,使用wxWidgets工具包生成C++代码。这章我们就来学习如何使用wxSmith!
创建一个新的wxWidgets项目(工程,project, whatever)。
File | New | Project... | wxWidgets project, Go
在Project title编辑框中输入MyNotePad。
选择wxSmith为首选GUI构建器
在项目生成完成后,将显示 以下文件窗口:
上面的窗口有以下三个主要组成部分:
wxSmith窗口:该窗口显示可编辑的UI元素
资源(Resource)树:该窗口提供项目的总体视图,显示特定项目的GUI元素的层次结构
属性(Property)窗口:该窗口显示在wxSmith窗口中当前选中对象的属性
在资源树上单击MyNotePadFrame项,然后在属性窗口单击Title属性,在文本框中输入MyNotePad。这将把我们应用程序的标题设置为MyNotePad。保存。
现在我们将添加一个wxTextCtrl控件到我们的程序中。这将在我们应用程序中添加一个文本输入框。单击下方工具栏上的wxTextCtrl控件按钮。
提示:下方工具上的控件按钮是以26个英文字母的顺序排列的,不包括前缀wx。
显示在wxSmith窗口内的MyNotePadFrame将被立即选中。
单击它,该文本输入框控件将被添加到它上面。
在属性窗口中改变如下属性:
Text:该属性存储该控件中的文本。此处将其置空。
Var name:该属性将会用来命名wxTextCtrl对象类。此处改为TextCtrlNotePad。
Identifier:该属性将被分配一个唯一的整数,然后将被用来给它分配一个事件处理器和事件类型
上面的话有点绕,简言之,就是唯一标识符,分配事件处理器和事件类型时要用到它。
向下滚动属性窗口并单击Style属性。点击wxTE_MULTILINE属性并勾选它。这将使得该控件能够显示多选文本。
接下来,我们编辑菜单栏。双击菜单栏图标,如下图所示
此时将会弹出MenuBar editor(菜单栏编辑器)。在左侧的菜单树中选择Quit菜单项,然后单击New button:
单击向上(^)按钮将new menu移到Quit菜单项上方。下图所示的四个按钮能被用来在菜单树中重新排列菜单项。
选中New Menu项,修改其如下属性:
Id:该属性会被定义为一个唯一的整数,并将为其分配一个事件处理器和事件类型。此处输入idFileOpen
Label:此处修改为&Open。该文本定义了菜单的显示文字。&O将定义一个快捷键。现在无论何时只要此菜单项能被看见,通过按键盘上的O键,此菜单项将被选中和点击。
Accelerator:此处输入Ctrl+O。该属性为此菜单项定义了键盘快捷键。键盘快捷键是一个独特的键盘击键组合,不管菜单项的可见性如何,该击键组合都将生成该菜单项的单击事件。
Help:输入Opens a file...。无论何时此菜单项被鼠标或者键盘选中时,此属性中的文本将会显示在状态栏中。
点击OK按钮关闭菜单栏编辑器。现在我们已经添加了一个菜单项到我们已经存在的菜单栏中。在我们为此菜单项打开一个文件添加代码之前,我们需要添加一个文件打开保存控件。
点击wxSmith下方工具栏上的Dialog页签,然后点击wxFileDialog控件按钮。这样将会添加一个标准的文件打开和保存的对话框到MyNotePadFrame类中。
在左侧的属性窗口中为其修改如下属性:
Wildcard:通配符,输入*.txt。这将使用.txt扩展名来设置文件的过滤器文本。
Var name:输入NotePadFileDialog。此值将用来创建一个wxFileDialog类对象,展现一个标准的打开或者保存对话框。
现在我们给新添加的菜单项编写代码。在资源树中点击&Open项,然后点击属性窗口中{}按钮。点击EVT_MENU右侧的下拉菜单并选择--Add new handler--菜单项,如下图所示:
在弹出的对话框中输入OnFileOpen,点击OK按钮。
此时代码编辑器会打开。在
MyNotePadFrame::OnFileOpen()函数(在打开的MyNotePadMain.cpp文件的最下方)中添加如下代码
int result = NotePadFileDialog->ShowModal();
if (result == wxID_OK)
{
wxTextFile textFile;
if (textFile.Open(NotePadFileDialog->GetPath()))
{
wxString fileContent;
for (size_t i = 0; i < textFile.GetLineCount(); i++)
{
fileContent << textFile.GetLine(i) << _t\r\n textfile.close textctrlnotepad->SetLabel(fileContent);
}
}
现在来解释上面的代码。
我们显示打开文件对话框使用ShowModal()函数,此函数的返回值将存储在result变量中。接下来的一行代码我们检查result的值是否等于wxID_OK——此值表明用户选择了一个文件。
我们打开一个文本文件使用Open()函数,此函数的参数是从打开文件对话框中获取的文件名。如果文件打开成功,我们将创建一个循环去一行行地读取该文件。
变量fileContent添加从文件中读取的一行,然后添加新行符(\r\n在Windows上表示新行)到行尾。当我们读完所有的行后,使用Colse()函数关闭打开的文件。
最后,我们将存储在fileContent变量中的文本显示在我们文本框控件中。
为了使用wxTextFile类,我们还需要包含另外头文件。在MyNotePadMain.cpp文件中,在#include <wx/msgdlg.h>行后添加如下代码
#include <wx/textfile.h>
现在我们准备编译我们的notepad应用程序。点击F9(build and run)。我们的应用运行后看起来会像下面这样:
点击File | Open菜单项,如下对话框会被打开
选择一个文本文件,此例中为了简便我们就创建了一个helloworld.txt来进行演示,选中它,点击打开按钮,此文件将会在我们的应用中被打开,如下所示
并且当我们选择Open菜单项时,状态栏会显示我们之前为此菜单项添加的帮助文本(help text)。
现在我们的应用程序正在工作!在CB的帮助下,我们写了大部分的GUI相关的代码。只手动编写打开文件这几行代码。CB提供了一个出色的跨平台和快速应用开发的平台。在Code::Blocks的帮助下,我们能很容易的使用此种方法开发一个GUI应用程序 。
练习:
我们已经学习并开发了我们的notepad应用在前面的章节中。然后,我们的应用被限制在只能打开一个文件。现在我们要扩展我们的应用,使其能够保存一个文本文件。
我们将执行如下步骤:
在file菜单下&Open菜单项后,添加菜单项&Save,键盘快捷键设为Ctrl+S,Id为idFileSave,Help text为Saves a file...。为此菜单项添加一个事件处理器,并添加事件处理器函数OnFileSave()。
最后在
MyNotePadFrame::OnFileSave()函数中添加如下代码
int result = NotePadFileDialog->ShowModal();
if (result == wxID_OK)
{
if (!TextCtrlNotePad->SaveFile(NotePadFileDialog->GetPath()))
{
wxMessageBox(_T("Couldn't save ") + NotePadFileDialog->GetPath(),
_T("Error"), wxOK | wxICON_ERROR);
}
}
此代码和我们在OnFileOpen()函数中写的代码相似。我们使用wxTextCtrl::FileSave()函数保存我们的文件。
第6行代码确保当一个文件不能被写入时,一个错误信息会被显示。
点击F9,程序运行效果如下
到这里,读者可能注意到,我们的保存文件对话框有点小瑕疵:对话框标题还是Select File;此处的打开按钮应该为保存。这点瑕疵的修改就留给各位读者作为练习吧!
最后给一点小提示:在使用Code::Blocks时,每次修改之后记得手动保存。否则在构建的时候, Code::Blocks不会为你自动保存,你的修改,就会看不到效果。目前笔者没有发现哪里可以设置的,如果读者发现了可以评论告知。
本文暂时没有评论,来添加一个吧(●'◡'●)