- 浏览: 263848 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
luoqiyi:
如果是在java节点呢?而且报出的异常就只是这样:java.l ...
ant解决OutOfMemoryError -
7先生:
好文章啊!
jvm垃圾回收参数配置 -
cuijiemin:
sbpya 写道捷敏同学,有缘啊,今天搜PG的这个语句时,跑到 ...
随机读取N条记录(MySQL、SQL Server、Access、Oracle、postgreSQL)|access -
sbpya:
捷敏同学,有缘啊,今天搜PG的这个语句时,跑到你的博客里来了, ...
随机读取N条记录(MySQL、SQL Server、Access、Oracle、postgreSQL)|access -
nomad2:
this is not the root cause. are ...
APPARENT DEADLOCK!!! Complete Status:
不知道原文地址,给出获得这篇文章的地址:http://kylix.linuxaid.com.cn/book/wxWindowstut/wxTutorial.html 这篇文章对于初学者非常有帮助
if (window.showTocToggle) { var tocShowText = "显示"; var tocHideText = "隐藏"; showTocToggle(); }
中文版说明
本教程由Gxl117翻译并将继续维护,这是本教程的第一稿,如果发现错误请与我(Email:gxl117@yahoo.com.cn)联系让我能及时修正它。之后还会对这个教程进行更多的扩充,欢迎广大网友提供意见。
本教程遵循GPL协议发布。
本许可授权你制作和发布本教程的拷贝,但在所有拷贝上要保留本版权声明和许可声明。
如果你准备出版本文档,请告之译者,以确保你获得本文档的最新版本。
对本文档的适用范围不作担保,它仅仅是作为一个免费的资源提供。因此,这里提供的这些信息的作者和维护者无法做出这些信息一定正确的保证。
Franky Braem
Copyright © 2001-2002 Franky Braem
You are allowed to copy and to print this book as long as you don't exploit the information commercially. The author of this book makes no warranty of any kind, expressed or implied, with regard to the programs or the documentation contained in this book.
Chapter 1. Introduction
Table of Contents
为什么使用 wxWindows?
你希望使用C++编写的同一个程序能够运行在 Windows, Linux 或者 Unix上吗? 当每一个平台都有它们自己的framework,外观、行为或者SDK时,这几乎是不可能的。当然你也肯定不想为每一个平台都重写你的程序,这将是极难维护的。
wxWindows是一个解决方案。wxWindows为你隐藏了全部平台相关的代码。它是一个与平台无关的framework,它有如下特点:
- 它是非常全面的,拥有很多实用的类。It is very complete. There are many utility classes.
- 它仍然在快速的发展中。It is still heavily developed.
- 支持很多的编译器与平台: Windows, Linux, Mac, Unix.
- 拥有大量的文档。There's a lot of documentation.
- 个人与商业机构都可以自由的使用它。It's free for personal and commercial use.
- 只要可能wxWindows就使用本地SDK。这表示如果一个程序是在Windows下编译的将有典型的windows程序的外观与行为, 当它在Linux下编译时它将拥有linux程序的外观与行为。
wxWindows 的历史
Julian Smart 1992年在爱丁堡大学的人工智能程序学院开始开发wxWindows。在1995年 Markus Holzem完成了Xt版本的移植。在1997年Windows 和 GTK+ 的移植版整合并放入了 CVS 档案库.
Hello World
这第一个例子是众所周知的Hello World程序。这个程序是一个在状态栏里显示"Hello World"的窗口。
每个wxWindow程序都要有一个继承自wxApp的对象。每个程序都要用OnInit()方法来实例化,你可以在这创建主窗口。 例 1.4 是 HelloWorldApp的定义:
Example 1.4. HelloWorldApp.h - The HelloWorldApp definition
#ifndef INCLUDED_HELLOWORLDAPP_H
#define INCLUDED_HELLOWORLDAPP_H
/**
* HelloWorldApp类 * 这个类显示一个状态栏中包含文本"Hello World"的窗口
*/
class HelloWorldApp: public wxApp
{
public: virtual bool OnInit();
};
DECLARE_APP(HelloWorldApp)
#endif // INCLUDED_HELLOWORLDAPP_H
对于主窗口我们使用wxFrame类。这个类提供了一个可以调整大小与位置的窗口。它有粗的边框与一个标题栏。另外你可以让它有一个菜单栏、工具栏、状态栏。例 1.5 是HelloWorldApp的实现.
例 1.5. HelloWorldApp.cpp - HelloWorldApp的实现
//对不支持预编译编译器要包含"wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "HelloWorldApp.h"
IMPLEMENT_APP(HelloWorldApp)
/* 程序从这里开始执行,类似非wxWindows程序中的main() */
bool HelloWorldApp::OnInit()
{
wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, _T("Hello World"));
frame->CreateStatusBar();
frame->SetStatusText(_T("Hello World"));
frame->Show(TRUE);
SetTopWindow(frame);
return true;
}
当你的编译器支持预处理器时,你可以使用wxprec头文件。当它不支持时,你应该包含wx.h,它包含了所有必须的wxWindows头文件。你同样也可以为每一个控件分别包含相对应的头文件。(译者注:在Linux之下使用wxFrame的构造函数对其中的字符串要使用wxChar进行显式转换,对于多字节字符的支持可以使用宏wxT(string)来解决)
宏 DECLARE_APP 和 IMPLEMENT_APP 为我们作下列操作:
当平台需要时,它创建一个 main() 或者 WinMain() 方法。它建立一个全局方法 wxGetApp(). 你能够使用这个函数去得到一个程序对象的引用:
- Example 1.6. wxGetApp() 使用方法
你可能会奇怪为什么在程序的任何地方都没有删除frame变量的代码。因为frame被设置为程序的顶层窗口所以程序将在退出时自动的删除 frame。
有一些糟糕的编译器不允许NULL隐式的转换到wxFrame*,所以这就是我们为什么要显示的作它,仅仅是出于稳妥的考虑(不过如果你真的在使用这样的编译器的话,我建议你还是更新它吧)。 同时这样作也更有利于程序的移植。
在frame建立之后,使用CreateStatusBar来创建一个状态栏。状态栏的文字内容设置为"Hello World".调用show()来显示frame。Show()是一个wxFrame从wxWindow类继承的方法。当OnInit返回false时,程序将立即停止。如果在程序初始化期间一些事情发生了错误,你可以利用它来停止程序。
第二章使用wxFrame
wxFrame类提供给我们一个框架窗口。框架窗口是一个可以改变大小的窗口,它有粗的边框与一个标题栏。另外你可以让它有一个菜单栏、工具栏、状态栏。框架可以作为其它控件的窗口器,但不能包含另一个窗口或对话框。wxFrame是从wxWindow类派生来的。
在这一章里我们将创建一个小小的文本编辑器。
创建 frame
通常你能够通过继承wxFrame来创建你自己的类。这样你可以向你自己的frame类中添加功能。 例2.1 就是这样作的,它的实现在例 2.2中。
例2.1 -定义 TextFrame
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
class TextFrame: public wxFrame
{
public:
/**
* 构造函数. 用来创建新的TextFrame
*/
TextFrame(const wxChar *title, int xpos, int ypos, int width, int height);
/**
* 析构函数
*/
~TextFrame();
};
#endif //_TEXTFRAME_H
TextFrame的构造函数继承自wxFrame的构造函数。
例 2.2. TextFrame 的实现
// 对支持预编译编译器要包含"wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "TextFrame.h"
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
}
TextFrame::~TextFrame()
{
}
构造函数
wxFrame(wxWindow* parent,
- parent 是一个指向父窗口的指针,当框架没有父窗口时使用NULL。
- id 是唯一的窗口标识号,当你不需要它时使用-1.
- title 是框架的标题,它将显示在框架的标题栏中。
- pos 是框架的位置。WxDefaultPosition表示默认值。
- size 是框架的大小。 WxDefaultSize表示使用默认值。
- style 是框架的风格。
表 2.1. wxFram风格
name 是窗口的名字。这个参数是用来将一个条目与一个名称相关联的。这允许用户去为每个窗口设置Motif资源值。
例 2.3 和例 2.4 是程序的实现
2.3. TextEditorApp.h - TextEditorApp 的定义
#ifndef TEXTEDITORAPP_H
#define TEXTEDITORAPP_H
class TextEditorApp: public wxApp
{
public:
/**
* 程序初始化
*/
virtual bool OnInit();
};
DECLARE_APP(TextEditorApp)
#endif // TEXTEDITORAPP_H
例 2.4. TextEditorApp.cpp - TextEditorApp 的实现
// 对支持预编译编译器要包含"wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "TextEditorApp.h"
#include "TextFrame.h"
IMPLEMENT_APP(TextEditorApp)
bool TextEditorApp::OnInit()
{
TextFrame *frame = new TextFrame("Simple Text Editor", 100, 100, 400, 300);
frame->Show(TRUE);
SetTopWindow(frame);
return true;
}
添加控件
现在已经创建了一个窗口框架,你需要添加一些控件来处理文本。类wxTextCtrl将是我们所需要的。框架类已经包含了这个控件。
例 2.5 是一个新的TextFrame类的定义。只有一件事是改变的,它添加了一个wxTextCtrl类型的成员。这个成员是在构造函数中初始化的。
例 2.5. TextFrame 的重新定义
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
class TextFrame: public wxFrame
{
public:
/**
* 构造函数. 用来创建新的TextFrame
*/
TextFrame(const wxChar *title, int xpos, int ypos, int width, int height);
/**
* 析构函数
*/
~TextFrame();
private:
wxTextCtrl *m_pTextCtrl;
};
#endif //_TEXTFRAME_H
例 2.6 是更新后的TextFraem类的构造函数。TextFrame是wxTextCtrl成员的父类。所以你应该传递this指针。字符串"Type some text..."将作为默认的文本。注意wxTextCtrl的构造函数看上去与wxFrame的相仿。这是因为每一个类都是从wxWindow继承来的所以有相同的构造函数模式。
另外,这里没有删除wxTextCtrl指针的代码。这里不需要它(实际上是不允许),因为当父类TextFrame撤消时它的所有子类都会自动的删除。
wxTE_MULTILINE 是文本控件专用的窗口风格。这种风格表示wxTextCtrl允许多行。
例2.6.TextFrame 的实现
// 对支持预编译编译器要包含"wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "TextFrame.h"
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, wxString("Type some text..."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
}
TextFrame::~TextFrame()
{
}
当你 build 这个项目时,你将拥有一个可以输入一些文本的窗口,你可以尝试在这个窗口中剪切、粘贴文本,你将会出现这些短短的代码已经为你作很多事了。
添加菜单栏
通常,我们总向自己的程序添加菜单栏来帮助用户操作程序, wxWindows 为菜单栏提供了下面的类:wxMenuBar 和 wxMenu.
每一个菜单都需要一个独立的ID。这是通过一个枚举类型来完成的。而不能使用#define定义的常量(比如:#define MENU_FILE_MENU 1)因为这不能保证你有独一无二的ID。它十分容易漏掉一些值并且当你想插入新的ID时这会变的十分难以维护。
请参考wxWindows 手册, wxWin 预定义了一些你在使用文档/视图 framework 时会用到的ID。
Example 2.7. TextFrame的定义
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
class TextFrame: public wxFrame
{
public:
/**
* Constructor. Creates a new TextFrame
*/
TextFrame(const wxChar *title, int xpos, int ypos, int width, int height);
/**
* Destructor
*/
~TextFrame();
private:
wxTextCtrl *m_pTextCtrl;
wxMenuBar *m_pMenuBar;
wxMenu *m_pFileMenu;
wxMenu *m_pInfoMenu;
enum
{
MENU_FILE_OPEN,
MENU_FILE_SAVE,
MENU_FILE_QUIT,
MENU_INFO_ABOUT
};
};
#endif //_TEXTFRAME_H
菜单栏是在TextFrame的构造函数中创建的。一个菜单项是使用wxMenu的Append方法添加到菜单中的。要注意&号是如何指出哪个字符是快捷键的。当菜单创建后你还要使用wxMenuBar的Append方法把它添加到菜单栏。
Example 2.8. TextFrame的实现
// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "TextFrame.h"
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, wxString("Type some text..."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
m_pMenuBar = new wxMenuBar();
// File Menu
m_pFileMenu = new wxMenu();
m_pFileMenu->Append(MENU_FILE_OPEN, "&Open");
m_pFileMenu->Append(MENU_FILE_SAVE, "&Save");
m_pFileMenu->AppendSeparator();
m_pFileMenu->Append(MENU_FILE_QUIT, "&Quit");
m_pMenuBar->Append(m_pFileMenu, "&File");
// About menu
m_pInfoMenu = new wxMenu();
m_pInfoMenu->Append(MENU_INFO_ABOUT, "&About");
m_pMenuBar->Append(m_pInfoMenu, "&Info");
SetMenuBar(m_pMenuBar);
}
TextFrame::~TextFrame()
{
}
添加状态栏
为框架添加一个状态栏是很容易的。使用wxFrame类中的CreateStatusBar方法来创建状态栏,它接受一个整形参数作为状态栏中的区域个数,使用SetStatusText方法来改变各域中的文本内容。
Example 2.9. 状态栏的创建
CreateStatusBar(3); SetStatusText("Ready", 0);
Example 2.9 创建一个有三个域的状态栏。第一个域包含文本"Ready"。
状态栏可用来显示对一个菜单项的描述。例2.10对上一节中的向菜单栏中添加菜单项的例2.8作了更改,以使菜单项与状态栏关联。当一个菜单项被选择时,相关的描述就会显示在状态栏的第一个域中。
例2.10包含功能描述的菜单项
// 文件菜单
m_pFileMenu = new wxMenu();
m_pFileMenu->Append(MENU_FILE_OPEN, "&Open", "Opens an existing file");
m_pFileMenu->Append(MENU_FILE_SAVE, "&Save", "Save the content");
m_pFileMenu->AppendSeparator();
m_pFileMenu->Append(MENU_FILE_QUIT, "&Quit", "Quit the application");
m_pMenuBar->Append(m_pFileMenu, "&File");
// 关于菜单
m_pInfoMenu = new wxMenu();
m_pInfoMenu->Append(MENU_INFO_ABOUT, "&About", "Shows information about the application");
m_pMenuBar->Append(m_pInfoMenu, "&Info");
处理菜单事件
现在frame上已经有了菜单,当用户选择一个菜单时我们要用一种方法来实现它的相应动作。每选择一个菜单都会产生一个事件。如何让一个动作与这个事件相关联呢?一个技巧就是将一个类的方法与事件相关联。在wxWindows的早期版本中这是通过使用回调函数或者通过重载虚拟函数来实现的。从wxWindows2.0开始改为使用事件表。在这一节里我们仅解释通过菜单产生的事件。关于事件处理的详细过程我们将在第三章解释。
要处理事件的每个类都需要声明一个事件表。宏DECLARE_EVENT_TABLE用来完成这项工作。每一个事件都必须有一个已经实现了的方法。每个方法都有一个参数用来包含事件的信息。从菜单获得的事件是一个wxCommandEvent类型的数据。例2.11是类TextFrame的完整定义。
例2.11. TextFrame.h的完整定义
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
class TextFrame: public wxFrame
{
public:
/**
* Constructor. Creates a new TextFrame
*/
TextFrame(const wxChar title, int xpos, int ypos, int width, int height);
/**
* Destructor
*/
~TextFrame();
/**
* Processes menu File|Open
*/
void OnMenuFileOpen(wxCommandEvent &event);
/**
* Processes menu File|Save
*/
void OnMenuFileSave(wxCommandEvent &event);
/**
* Processes menu File|Quit
*/
void OnMenuFileQuit(wxCommandEvent &event);
/**
* Processes menu About|Info
*/
void OnMenuInfoAbout(wxCommandEvent &event);
protected:
DECLARE_EVENT_TABLE()
private:
wxTextCtrl *m_pTextCtrl;
wxMenuBar *m_pMenuBar;
wxMenu *m_pFileMenu;
wxMenu *m_pInfoMenu;
enum
{
MENU_FILE_OPEN,
MENU_FILE_SAVE,
MENU_FILE_QUIT,
MENU_INFO_ABOUT
};
};
#endif //_TEXTFRAME_H
事件表是放在实现文件中的,wxWindows通过一些宏来帮助的完成事件表的声明。宏BEGIN_EVENT在事件表声明的开始处使用,因为在一个程序中可能不止一个事件表,要将事件处理过程相关的类名传递给宏。将一个方法与事件关联要使用EVT_MENU宏。这个宏需要菜单ID与事件名。在事件表的最后用宏END_EVENT_TABLE作结束标记。例2.12显示了完整的实现文件。
Example 2.12. TextFrame.cpp - The full implementation
// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "TextFrame.h"
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, wxString("Type some text..."),
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
CreateStatusBar();
m_pMenuBar = new wxMenuBar();
// File Menu
m_pFileMenu = new wxMenu();
m_pFileMenu->Append(MENU_FILE_OPEN, "&Open", "Opens an existing file");
m_pFileMenu->Append(MENU_FILE_SAVE, "&Save", "Saves the file");
m_pFileMenu->AppendSeparator();
m_pFileMenu->Append(MENU_FILE_QUIT, "&Quit, "Close the application");
m_pMenuBar->Append(m_pFileMenu, "&File");
// About menu
m_pInfoMenu = new wxMenu();
m_pInfoMenu->Append(MENU_INFO_ABOUT, "&About", "Shows info about the application");
m_pMenuBar->Append(m_pInfoMenu, "&Info");
SetMenuBar(m_pMenuBar);
}
TextFrame::~TextFrame()
{
}
BEGIN_EVENT_TABLE(TextFrame, wxFrame)
EVT_MENU(MENU_FILE_OPEN, TextFrame::OnMenuFileOpen)
EVT_MENU(MENU_FILE_SAVE, TextFrame::OnMenuFileSave)
EVT_MENU(MENU_FILE_QUIT, TextFrame::OnMenuFileQuit)
EVT_MENU(MENU_INFO_ABOUT, TextFrame::OnMenuInfoAbout)
END_EVENT_TABLE()
void TextFrame::OnMenuFileOpen(wxCommandEvent &event)
{
wxLogMessage("File Open Menu Selected");
}
void TextFrame::OnMenuFileSave(wxCommandEvent &event)
{
wxLogMessage("File Save Menu Selected");
}
void TextFrame::OnMenuFileQuit(wxCommandEvent &event)
{
Close(FALSE);
}
void TextFrame::OnMenuInfoAbout(wxCommandEvent &event)
{
wxLogMessage("File About Menu Selected");
}
第三章事件处理
目录
介绍它是如何工作的事件跳转禁止事件加挂事件句柄
在上一章里已经学习了如何处理菜单事件。这章将解释事件处理是如何工作的,同时解释了如何去处理其它事件。
介绍Introduction
事件是出现在程序内部或外部的一些事情。一个事件可能是通过用户或是其它程序、操作系统等来触发的。这时需要一个机制来让程序对期望的事件产生反应。
在wxWindows的早期版本中,程序的事件处理是完全通过回调函数或者重载虚拟函数来实现的。从wxWindows2.0开始 转而使用事件表了。如例3,事件表告诉wxWindows将事件映射到成员函数。事件表是在实现文件(cpp)中声明的。
例 3.1.事件表
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
EVT_SIZE(MyFrame::OnSize)
EVT_BUTTON(BUTTON1, MyFrame::OnButton1)
END_EVENT_TABLE()
上面的事件表告诉wxWindows当它接收到一个WM_SIZE事件时调用MyFrame的成员函数OnSize。 宏 BEGIN_EVENT_TABLE 声明wxFrame和它的子类MyFrame拥有这个事件表。
处理事件的成员函数不能是虚拟的。实际上事件处理器将忽略虚拟声明。事件处理函数有类似的形式:返回类型为void并且接受一个事件参数。这个参数的类型与具体的事件相关。对于size事件,使用的类型是wxCommandEvent。当控件变的更复杂时它们使用自己的事件类。
在类定义中,必须有一个DECLARE_EVENT_TABLE宏。参见例2.11。
所有这些宏隐藏了复杂的事件处理系统。
它是如何工作的?
当接收到一个事件时,wxWindows首先调用窗口上产生事件的对象上的wxEventHandler的ProcssEvent处理器。wxWindow(和其它的窗口类)继承自wxEventHander。ProcessEvent查找事件表里的每一个事件并且调用零或多个事件处理器函数。下面是处理一个事件的步骤:
1. 当对象关闭时(包括wxEvtHandler的SetEvtHandle)函数跳转到第六步。
2. 如果对象是一个wxWindow对象,ProcessEvent在窗口的wxValidator上递归调用。
如果返回真函数退出。
3. SearchEventTable是事件处理器调用的函数。当它失败时,开始在基类上尝试直到
没有更多的事件表或者发现了一个合适的函数时这个函数退出。被发现的函数开始执行。
4. 查找过程应用于整个事件处理器链,当应用成功时(表示事件处理完毕)函数退出。
5. 当对象是一个wxWindow对象时,并且事件为wxCommandEvent类型时,
ProcessEvent向上递归应用于父窗口的事件处理器。当它返回真,函数退出。
这可以让一个按钮的父亲来处理按钮的点击而不是让按钮自己来处理。
6. 最后ProcessEvent 在wxApp对象上调用。
事件跳转Event skipping
ProcessEvent在发现一个可以处理事件的函数后退出。这表示当你的类对一个事件起反应时,下层的类不会得到这个事件。有时我们不希望这样。这个问题可以根据基类的事件类型用wxEvent类的Skip方法来解决,使事件处理器的查找继续进行。
下面的例子展示了事件跳转的用处。例3.2是一个文本控件的定义,它只接受数字字符。
例 3.2. NumTextCtrl.h
class NumTextCtrl: public wxTextCtrl
{
public:
NumTextCtrl(wxWindow *parent);
void OnChar(wxKeyEvent& event);
protected:
DECLARE_EVENT_TABLE()
};
当NumericTextCtrl接收到一个键盘事件时,就进行keycode检查。如果输入的是数字,基类wxTextCtrl就可以处理这个事件。这就是我们要对这个事件使用跳转的原因。你必须在这调用Skip方法,否则基类不会处理任何键。
例3.3. NumTextCtrl.cpp
// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "NumTextCtrl.h"
#include <ctype.h>
NumTextCtrl::NumTextCtrl(wxWindow *parent): wxTextCtrl(parent, -1)
{
}
void NumTextCtrl::OnChar(wxKeyEvent& event)
{
if ( isdigit(event.GetKeyCode()) )
{
// Numeric characters are allowed, so the base class wxTextCtrl
// is allowed to process the event. This is done using the Skip() method.
event.Skip();
}
else
{
// Character is not allowed.
wxBell();
}
}
BEGIN_EVENT_TABLE(NumTextCtrl, wxTextCtrl)
EVT_CHAR(NumTextCtrl::OnChar)
END_EVENT_TABLE()
禁止事件
一些事件是可以禁止的。当你禁止一个事件时,这个事件不会被进一步处理。例3.4演示了,当一个文本控件内的文本改变后如何禁止这个简单文本编辑器的关闭事件。这表示当在用户还没有保存改变后的文本内容时这个窗口不能被关闭。
例 3.4. 禁止事件
void TextFrame::OnClose(wxCloseEvent& event)
{
bool destroy = true;
if ( event.CanVeto() )
{
if ( m_pTextCtrl->IsModified() )
{
wxMessageDialog *dlg =
new wxMessageDialog(this, "Text is changed!\nAre you sure you want to exit?",
"Text changed!!!", wxYES_NO | wxNO_DEFAULT);
int result = dlg->ShowModal();
if ( result == wxID_NO )
{
event.Veto();
destroy = false;
}
}
}
if ( destroy )
{
Destroy();
}
}
当CanVeto返回false时程序作什么呢?你将不能禁止这个事件你的程序将会退出。阻塞事件处理器Plug an event handler
考虑下面的问题:每个菜单命令都必须被记录。一个解决方案是创建一个在每个命令事件处理函数中调用的函数。这种方法带来的问题是使维护变得十分困难。当添加一个新的菜单并且没有调用这个函数时,这个菜单命令将不被记录。
解决这个问题是去创建一个新的事件处理器并添加到一个wxWindow类。要完成它需要创建一个从wxEvtHandler派生的新类。在新类中处理事件与一个正常的窗口是相同的。
例 3.5. LogEventHandler.h -LogEventHandler的定义
#ifndef _LogEventHandler_H
#define _LogEventHandler_H
class LogEventHandler: public wxEvtHandler
{
public:
LogEventHandler(): wxEvtHandler()
{
}
virtual ~LogEventHandler()
{
}
protected:
DECLARE_EVENT_TABLE()
void OnMenu(wxMenuEvent &event);
private:
};
#endif // _LogEventHandler_H
例3.6. LogEventHandler.cpp - LogEventHandler的实现
// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "LogEventHandler.h"
void LogEventHandler::OnMenu(wxMenuEvent &event)
{
wxLogMessage("Someone selected a menu item");
event.Skip();
}
BEGIN_EVENT_TABLE(LogEventHandler, wxEvtHandler)
EVT_MENU_RANGE(-1, -1, LogEventHandler::OnMenu)
END_EVENT_TABLE()
在宏EVT_MENU_RANGE里,所有的菜单事件都可以被处理。前两个参数用来指定要处理的菜单的ID范围。-1表示处理所有的菜单项。不要忘记在事件上调用Skip,否则不会有任何事件传递到类wxWindow的事件处理器。
下一步是把新的事件处理器压入处理器栈。这是使用wxWindow的PushEventHandler来完成的。要从栈上移除事件处理器使用PopEventHandler。
PushEventHandler(new LogEventHandler());
PopEventHandler 有一个布尔类型的参数,当这个参数为真时,wxWindows删除事件处理器。注意在没有事件处理器被取出时,wxWndows将在窗口撤消时尝试删除事件处理器。这在访问在栈上创建的事件处理器时会发生一个访问错误。可以在一个类撤消之前调用使用false参数的PopeventHandler来避免这个问题。
Chapter 4. 通用对话框
Table of Contents
wxFileDialog
Constructor Methods Example wxFileSelector
wxColourDialog
Constructor Methods wxColourData Example wxGetColourFromUser
wxFontDialog
Constructor Methods wxFontData Example
wxPrintDialog
Constructor Methods Example
wxDirDialog
Constructor Methods Example wxDirSelector
wxTextEntryDialog
Constructor Methods Example wxGetTextFromUser wxGetPasswordFromUser
wxMessageDialog
Constructor Methods Example wxMessageBox
wxSingleChoiceDialog
Constructor Methods Example wxGetSingleChoice wxGetSingleChoiceIndex wxGetSingleChoiceData
在第二章的例子中有打开与存储一个文本文件的菜单命令。这时要使用一个通用对话框wxFileDialog来让用户选择或者输入一个文件名。在使用通用对话框时,用户得到一个统一的界面。这可以让用户不管在什么样的程序中都可以看到类似的对话框。
wxWindows提供了下列通用对话框。
* wxFileDialog 一个存储或打开文件的对话框。
* wxColourDialog 一个选择颜色的对话框。
* wxFontDialog 选择字体的对话框。
* wxPrintDialog 用于打印与设置打印机的对话框。
* wxDirDialog 选择目录的对话框。
* wxTextEntryDialog 请求用户输入一行文本的对话框。
* wxMessageDialog 用于显示一行或多行信息,可包括OK,Yes,No,与Cancel按钮。
* wxSingleChoiceDialog 显示一个包含字符串列表的对话框,并且允许用户选择其中一个。
wxWindows 是交叉平台的FrameWork。当一个通用对话框在某个特别的平台上不能使用时,wxWindow将显示一个一般对话框。注意
在下面的每一个对话框的例子中,将使用Destroy方法来代替用删除指针的方法来撤消窗口。这是为了稳定的目的。WxWindows控件应该总是在堆上创建并且使用Destroy方法来安全的移除。因为wxWindows有时会延迟删除,直到所有事件都被处理完毕。这样wxWindows可以避免将事件发送到一个不存在的窗口上。
wxFileDialog
wxFileDialog 为用户提供一个当用户在打开或者储存一个文件时可以选择或者输入文件名的对话框。一个全局方法wxFileSelector同样可以用来让用户选择一个文件。详情请看章节 “wxFileSelector”. 构造函数
#include <wx/filedlg.h>
wxFileDialog(wxWindow* parent,
const wxString& message= "Choose a file",
const wxString& defaultDir= "",
const wxString& defaultFile= "",
const wxString& wildcard= "",
long style= 0,
const wxPoint& pos= wxDefaultPosition);
* parent 拥有这个对话框的窗口。
* message 对话框的标题。
* defaultDir 默认目录。
* defaultFile 默认文件名。
* wildcard 是一些类似 "*.*" or "*.txt"之类的字符串。这是用来过滤文件的。它的语法为 描述|后缀。例 "All files(*.*)|*.*|Text files(*.txt)|*.txt|Bitmap files(*.bmp)|*.bmp".
* style 对话框的类型。
表 4.1. wxFileDialog 风格
- wxCHANGE_DIR 改变当前目录
- wxFILE_MUST_EXIST 输入的文件必须存在
- wxHIDE_READONLY 隐藏只读文件
- wxMULTIPLE 只是一个打开对话框,允许选择多个文件。
- wxOPEN 只是一个打开对话框。
- wxOVERWRITE_PROMPT 当一个文件将被覆写时询问已确定。
- wxSAVE 一个保存对话框。
- pos 没有使用。
方法
public void SetDirectory(const wxString& dir);
public wxString GetDirectory();
设置与得到当前目录
public void SetFilename(const wxString& name);
public wxString GetFilename();
设置与得到当前文件名
public const void GetFilenames(wxArrayString& files);
使用所选择的文件名来添充文件名数组。这个函数只用于wxMULTIPLE风格的对话框。其它的使用GetFilename。
public void SetFilterIndex(int filterIndex);
public int GetFilterIndex();
设置与得到给出的过滤器列表的索引。在对话框显示之前,这个索引决定对话框显示时首先使用的过滤器。在显示之后这个索引由用户选择。
public void SetMessage(const wxString& message);
public wxString GetMessage();
设置与等到新的对话框标题。
public void SetPath(const wxString& path);
public wxString GetPath();
设置与得到当前路径(目录与文件名)
public void SetStyle(long style);
public long GetStyle();
设置与得到对话框的风格,参看“Constructor”
public void GetPaths(wxArrayString& paths);
用所选择的文件绝对路径名来填充路径数组。这个函数仅仅用于wxMULTIPLE风格的对话框。其它的使用GetPath。
public void SetWildcard(const wxString& wildCard); public wxString GetWildcard();
设置与得到wildcard参见“Constructor”
public int ShowModal();
显示对话框,当用户按下OK时返回wxID_OK。其它情况返回wxID_CANCEL。例
在第二章的文本编辑器例子中,使用ShowModal来显示一个对话框。”Modal”表示在对话框关闭之前程序的其它窗口不能得到焦点。使用ShowModal 显示对话框时,当用户按下OK时返回wxID_OK。其它情况返回wxID_CANCEL。 GetFilename 是用来得到选择的文件的文件名。GetPath 将返回所选择文件的完整路径(目录与文件名)。在使用wxTextCtrl控件时加载与保存文件是非常简单的。方法 LoadFile 和 SaveFile分别用于加载与保存文件。
例 4.1. wxFileDialog的使用
void TextFrame::OnMenuFileOpen(wxCommandEvent &event)
{
wxFileDialog *dlg = new wxFileDialog(this, "Open a text file", "", "",
"All files(*.*)|*.*|Text Files(*.txt)|*.txt",
wxOPEN, wxDefaultPosition);
if ( dlg->ShowModal() == wxID_OK )
{
m_pTextCtrl->LoadFile(dlg->GetFilename());
SetStatusText(dlg->GetFilename(), 0);
}
dlg->Destroy();
}
void TextFrame::OnMenuFileSave(wxCommandEvent &event)
{
wxFileDialog *dlg = new wxFileDialog(this, "Save a text file", "", "",
"All files(*.*)|*.*|Text Files(*.txt)|*.txt",
wxSAVE, wxDefaultPosition);
if ( dlg->ShowModal() == wxID_OK )
{
m_pTextCtrl->SaveFile(dlg->GetPath());
SetStatusText(dlg->GetFilename(), 0);
}
dlg->Destroy();
}
wxFileSelector
wxFileSelector 弹出一个文件选择框。当用户忽略它时返回一个空字符串。
wxString wxFileSelector(const wxString& message,
const wxString& defaultPath= "",
const wxString& defaultFile= "",
const wxString& defaultExtension= "",
const wxString& wildcard= "*.*",
int flags= 0,
wxWindow* parent= NULL,
int x= -1,
int y= -1);
- message 文件选择器的标题。
- defaultPath 默认路径i
- defaultFile 默认文件
- defaultExtension 默认的后缀。当用户省略后缀时这个后缀将自动添加到文件后。当没有指定wildcard时,wxWindows自动附加一个过滤器。
- wildcard (参见 wxFileDialog 构造函数).
- flags 是对话框的风格。参见wxFileDialog 构造函数。不支持 wxMULTIPLE风格
- parent 父窗口
- x 选择器的x轴位置。
- y 选择器的y轴位置。
例
例4.2 要求用户选择一个 JavaScript 文件。
例4.2. wxFileSelector的使用。
wxString selection = wxFileSelector("Open a Javascript file", "", "", "js",
"All files(*.*)|*.*|JavaScript Files(*.js)|*.js|Text Files(*.txt)|*.txt",
wxOPEN, this);
wxColourDialog
wxColourDialog实现了一个供用户选择颜色的窗口。WxColourDialog是与wxColourdata共同使用的。WxColourData是用来在对话框中设置当前颜色并用来得到选择的颜色。构造函数
#include <wx/colordlg.h>
wxColourDialog(wxWindow* parent,
wxColourData* data= NULL);
- parent i是我们这个对话框的父窗口。
- data 包含颜色信息。它包括默认颜色,定制颜色并且在windows之下你可以告诉它显示一个包含自定义颜色选择控件的填充对话框。
方法
public wxColourData& GetColourData();
得到与这个对话框关联的coloudata的引用。
public void SetTitle(const wxString& title);
public wxString GetTitle();
设置或得到对话框的标题
public int ShowModal();
显示对话框,当用户按下OK时返回wxID_OK。其它情况返回wxID_CANCEL。
wxColourData
这个类包含与wxColourDialog相关的信息。
构造函数
wxColourData();
默认构造函数
wxColourData(const wxColourData& data);
拷贝构造函数
方法
public void SetChooseFull(bool flag);
public bool GetChooseFull();
在windows上,这个方法显示一个包含自定义颜色选择控件的对话框,默认值为true。
public void SetColour(wxColour& colour);
public wxColour& GetColour();
设置或者得到选择的颜色。
public void SetCustomColour(int i, wxColour& colour);
public wxColour GetCustomColour(int i);
设置或得到给定位置的自定义颜色。I必须在0与15之间。例
例4.3 为程序添加一个菜单项允许用户选择其它的背景颜色。当前的背景色被赋给colourData。如果程序是运行在windows下的话将显示一个填充对话框。
例4.3.wxColourDialog的使用
void TextFrame::OnMenuOptionBackgroundColor(wxCommandEvent &event)
{
wxColourData colourData;
wxColour colour = m_pTextCtrl->GetBackgroundColour();
colourData.SetColour(colour);
colourData.SetChooseFull(true);
wxColourDialog *dlg = new wxColourDialog(this, &colourData);
if ( dlg->ShowModal() == wxID_OK )
{
colourData = dlg->GetColourData();
m_pTextCtrl->SetBackgroundColour(colourData.GetColour());
m_pTextCtrl->Refresh();
}
dlg->Destroy();
}
wxGetColourFromUser
wxGetColourFromUser 显示颜色选择对话框并返回用户选择的颜色或者在用户取消对话框时返回一个无效的颜色。使用wxColour的OK方法来测试颜色是否有效。
wxColour wxGetColourFromUser(wxWindow* parent= NULL,
const wxColour& colInit= wxNullColour);
- parent 选择器的父窗口。
- colInit 初始颜色。
例
例4.4 要示用户选择一个颜色
例4.4. wxGetColourFromUser的使用
wxColour colour = wxGetColourFromUser();
if ( colour.Ok() )
{
// 用户选择的颜色
}
wxFontDialog
wxFontDialog是供用户选择字体的对话框。这个对话框与wxFontData,wxFont和wxColour 一起使用。WxFontData用于设置对话框内的当前字体并得到选择的字体。构造函数
#include <wx/fontdlg.h>
wxColourDialog(wxWindow* parent,
wxFontData* data= NULL);
- parent 对话框的父窗口
- data 包含字体信息。它包含默认字体、当前字体颜色等信息。
方法
public wxFontData& GetFontData();
得到与对话框关联的fontdata的引用。
public int ShowModal();
显示对话框,当用户按下OK时返回wxID_OK。其它情况返回wxID_CANCEL。
wxFontData
wxFontData();
默认构造函数
public void EnableEffects(bool flag);
public bool GetEnableEffects();
在 Windows上, 指出是否使用字体效果比如下划线、斜体等。
public void SetAllowSymbols(bool flag);
public bool GetAllowSymbols();
在 Windows上,指出是否可以选择符号字体。
public void SetColour(const wxColour& colour);
public wxColour & GetColour();
设置或得到字体颜色。
public void SetShowHelp(bool flag);
public bool GetShowHelp();
On 在windows上,指出是否显示”帮助“按钮。
public void SetInitialFont(const wxFont& font);
public wxFont GetInitialFont();
得到或设置对话框使用的原始字体。
public wxFont GetChosenFont();
得到选择的字体。
public void SetRange(int minRange,
int maxRange);
在windows上,指出字体大小最大与最小值。默认情况下为0到无限。例
Example 例4.5 为第二章的文本编辑器实现了一个新的菜单项来改变编辑器内的字体。首先fontdata用当前的字体与颜色填充,当程序在Windows上运行时,用户将看到帮助按钮。当用户选择了字体时,fontdata将被赋与新的字体与文本控件的前景色。
例4.5. wxFontDialog的使用
void TextFrame::OnMenuOptionFont(wxCommandEvent& event)
{
wxFontData fontData;
wxFont font;
wxColour colour;
font = m_pTextCtrl->GetFont();
fontData.SetInitialFont(font);
colour = m_pTextCtrl->GetForegroundColour();
fontData.SetColour(colour);
fontData.SetShowHelp(true);
wxFontDialog *dlg = new wxFontDia发表评论
相关推荐
《wxWidgets跨平台程序开发》系统地介绍了wxWidgets及其跨平台程序开发。全书共有20章,第·1·章简要介绍了·wxWidgets·的发展历史和框架结构,第2章介绍了wxWidgets的程序框架及其实现,第3章深入剖析了wxWidgets...
使用wxWidgets进行开发之前,需要熟悉C++编程语言,并且具备一定的GUI应用程序开发经验。本书并不讲解C++语法或算法,而是假设读者已经具备这些知识。在实际开发之前,需要在自己的系统上设置开发环境。对于Linux...
wxWidgets 是一个开源的 C++ 库,它允许开发者使用标准的 C++ 编程语法创建跨平台的图形用户界面(GUI)应用程序。这个库提供了丰富的控件集和功能,使得开发者可以编写一次代码,就能在多个操作系统上运行,包括 ...
《使用wxWidgets进行跨平台程序开发》是一本深入讲解如何利用wxWidgets库构建跨平台应用程序的专业书籍。wxWidgets是一个开源的C++库,它允许开发者使用标准的C++语法编写一次代码,然后在多种操作系统上运行,包括...
《使用wxWidgets进行跨平台程序开发》这本书是程序员们学习如何使用wxWidgets库构建跨平台应用程序的重要资源。wxWidgets是一个开源的C++库,它允许开发者使用标准的C++编写代码,同时能在多个操作系统上运行,包括...
### 使用wxWidgets进行跨平台程序开发 #### 一、wxWidgets简介 **wxWidgets** 是一个用于构建跨平台用户界面的工具包。它提供了一套丰富的控件集合,这些控件模仿了各种操作系统(如Windows、macOS和Linux)中的...
wxWidgets库的使用,简化了C++程序员创建GUI(图形用户界面)的复杂性,同时也保持了原生的系统外观和感觉。 wxWidgets库基于事件驱动模型,该模型是现代GUI编程的基础。通过这个模型,用户界面的元素(如按钮、...
《C++跨平台编程与wxWidgets》是一本详细介绍如何使用C++和...通过阅读《C++跨平台编程与wxWidgets》,开发者可以掌握使用C++和wxWidgets创建功能丰富的跨平台应用程序的技能,从而拓宽开发视野,提升职业竞争力。
在"使用wxWidgets进行跨平台程序开发随书源码"中,你将找到一系列的示例代码,帮助你理解和掌握如何利用 wxWidgets 进行实际项目开发。 **跨平台开发的优势** 使用 wxWidgets 进行跨平台开发的主要优点包括: 1. ...
标题与描述:“wxwidgets_跨平台程序开发” wxWidgets是一种跨平台的C++图形用户界面(GUI)工具包,它允许开发者创建具有本地外观和感觉的应用程序,而无需修改代码即可在多个操作系统上运行。这一特性使得...
一个简单的wxWidgets程序通常从继承`wxApp`类开始,然后创建一个`wxFrame`作为应用程序的主要窗口。在窗口中添加控件,如`wxButton`、`wxTextCtrl`等,可以通过事件处理函数响应用户的操作。 ```cpp #include #...
《使用wxWidgets进行跨平台程序开发》是一本深入探讨如何使用wxWidgets库创建跨平台应用程序的专业书籍。wxWidgets是一个开源的C++库,它允许开发者使用一种编程语言和API来编写能够在多种操作系统上运行的应用程序...
WxWidgets是一个强大的开源库,它允许程序员使用C++编写跨平台的应用程序,可以在Windows、Linux、macOS等多种操作系统上运行。WxWidgets的核心理念是提供一个与平台无关的API,使得开发者可以专注于应用程序的逻辑...
3. "VS2010配置wxWidgets开发环境(窗口程序和控制台程序详细说明) - chenjinxian88的专栏 - 博客频道 - CSDN.NET_files" - 这个文件夹可能包含了与第一篇文章相关的图片、代码片段或其他辅助材料,帮助读者更好地...
wxDev-C++是一个集成开发环境(IDE),特别设计用于使用wxWidgets库进行C++开发。它提供了代码编辑器、项目管理、调试器等功能,简化了使用wxWidgets开发过程。通过wxDev-C++,开发者能够更方便地创建和管理基于...
在"使用C++开发GUI"这个教程中,你将学到如何选择合适的库、如何设置项目、如何编写GUI代码,以及如何调试和优化GUI应用。无论你是初学者还是有经验的开发者,这个教程都会为你提供宝贵的知识和技能。
在C++编程中,开发窗体程序是一种常见的需求,它涉及到图形用户界面(GUI)的构建,使得用户可以通过直观的窗口进行交互。本压缩包文件"**c++ 窗体程序17例**"提供了关于C++窗体程序设计的多个示例,这些示例覆盖了...