wxWidgets 对话框
对话框窗口或者对话框是现代GUI应用程序重要的组成部分。一次对话被定义为两个或两个以上的人之间的谈话,在计算机中对话框是一个被用来和程序交流的窗口。对话框被用来输入数据、修改数据或者改变应用程序的设置。对话框是人和计算机之间交流的重要手段。
基本上有两种类型的对话框,预定义的对话框和自定义的对话框。
预定义的对话框
预定义的对话框是wxWidgets工具集中可用的一个对话框组件,这些对话框被用来完成一些基本任务,例如显示一段文本、接收输入、加载或者保存文件。它们大大节省了程序员的时间并且带有一些基本行为。
消息对话框
消息对话框用来把信息显示给用户,它们是可以定制的,我们能够修改对话框上面的图标和按钮。
main.h
1 //消息对话框 2 #include <wx/wx.h> 3 //定义主框架窗口 4 class Message : public wxFrame 5 { 6 public: 7 Message(const wxString & title); 8 9 //定义了4个事件处理函数 10 void ShowMessage1(wxCommandEvent & event); 11 void ShowMessage2(wxCommandEvent & event); 12 void ShowMessage3(wxCommandEvent & event); 13 void ShowMessage4(wxCommandEvent & event); 14 15 enum{ID_INFO, ID_ERROR, ID_QUESTION, ID_ALERT}; 16 }; 17 18 class MyApp : public wxApp 19 { 20 public: 21 virtual bool OnInit(); 22 };
main.cpp
1 #include "main.h" 2 3 Message::Message(const wxString & title) 4 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(210, 110)) 5 { 6 //定义了一个Panel放置在wxFrame上 7 wxPanel * panel = new wxPanel(this, wxID_ANY); 8 9 //定义了一个水平布局控件wxBoxSizer 10 wxBoxSizer * hbox = new wxBoxSizer(wxHORIZONTAL); 11 //定义了一个布局控件wxGridSizer,2行 2列 垂直间隔为2 水平间隔2 12 wxGridSizer * gs = new wxGridSizer(2, 2, 2, 2); 13 //在Panel中添加了4个按钮 14 wxButton * btn1 = new wxButton(panel, ID_INFO, _T("Info")); 15 wxButton * btn2 = new wxButton(panel, ID_ERROR, _T("Error")); 16 wxButton * btn3 = new wxButton(panel, ID_QUESTION, _T("Question")); 17 wxButton * btn4 = new wxButton(panel, ID_ALERT, _T("Alert")); 18 19 //将4个按钮添加到布局wxGridSizer上 20 gs->Add(btn1, 1, wxEXPAND); 21 gs->Add(btn2, 1); 22 gs->Add(btn3, 1); 23 gs->Add(btn4, 1); 24 25 //动态关联了4个按钮的点击事件处理函数 26 Connect(ID_INFO, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Message::ShowMessage1)); 27 Connect(ID_ERROR, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Message::ShowMessage2)); 28 Connect(ID_QUESTION, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Message::ShowMessage3)); 29 Connect(ID_ALERT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Message::ShowMessage4)); 30 31 //将wxGridSizer布局控件添加到水平布局控件wxBoxSizer中 32 hbox->Add(gs, 0, wxALL, 15); 33 //将wxBoxSizer布局控件放置在Panel中 34 panel->SetSizer(hbox); 35 //使窗口在屏幕上居中显示 36 Centre(); 37 } 38 39 void Message::ShowMessage1(wxCommandEvent & event) 40 { 41 //定义一个对话框 42 wxMessageDialog * dial = new wxMessageDialog(NULL, _T("Download completed"), _T("Info"), wxOK); 43 //显示对话框 44 dial->ShowModal(); 45 } 46 void Message::ShowMessage2(wxCommandEvent & event) 47 { 48 wxMessageDialog * dial = new wxMessageDialog(NULL, _T("Error loading file"), _T("Error"), wxOK | wxICON_ERROR); 49 dial->ShowModal(); 50 } 51 void Message::ShowMessage3(wxCommandEvent & event) 52 { 53 wxMessageDialog * dial = new wxMessageDialog(NULL, _T("Are you sure to quit?"), _T("Question"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); 54 dial->ShowModal(); 55 } 56 void Message::ShowMessage4(wxCommandEvent & event) 57 { 58 wxMessageDialog * dial = new wxMessageDialog(NULL, _T("Unallowed Operation"), _T("Exclamation"), wxOK | wxICON_EXCLAMATION); 59 dial->ShowModal(); 60 } 61 //声明应用程序 62 IMPLEMENT_APP(MyApp) 63 64 bool MyApp::OnInit() 65 { 66 Message * msgs = new Message(_T("Message")); 67 msgs->Show(true); 68 69 return true; 70 }
在我们的例子中,我们创建了四个按钮,并把它们当在一个网格布局控件中,这四个按钮会显示四个不同的对话框窗口,我们通过指定不同的类型标识符来创建它们。
1 wxMessageDialog * dial = new wxMessageDialog(NULL, _T("Error loading file"), _T("Error"), wxOK | wxICON_ERROR); 2 dial->ShowModal();
创建消息对话框是很简单的,我们通过把parent参数设为NULL把对话框放在桌面顶层,接下来两个参数指定了对话框显示的消息和它的标题。我们通过指定wxOK和wxICON_ERROR标识来显示一个OK按钮和一个错误图标,调用ShowModal()方法显示对话框。
wxFileDialog
这是一个用来打开或者保存文件的常用对话框
main.h
1 //文件对话框wxFileDialog 2 #include <wx/wx.h> 3 4 //定义主框架类 5 class Openfile : public wxFrame 6 { 7 public: 8 Openfile(const wxString & title); 9 10 void OnOpen(wxCommandEvent & event); 11 12 //定义一个静态文本框 13 wxTextCtrl * tc; 14 }; 15 16 class MyApp : public wxApp 17 { 18 public: 19 virtual bool OnInit(); 20 };
main.cpp
1 #include "main.h" 2 3 Openfile::Openfile(const wxString & title) 4 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200)) 5 { 6 //定义菜单栏 7 wxMenuBar * menubar = new wxMenuBar; 8 //定义菜单 9 wxMenu * file = new wxMenu; 10 file->Append(wxID_OPEN, _T("&Open")); 11 //将菜单添加到菜单栏 12 menubar->Append(file, _T("&File")); 13 //将菜单栏添加值wxFrame 14 this->SetMenuBar(menubar); 15 //动态关联事件处理函数 16 Connect(wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, 17 wxCommandEventHandler(Openfile::OnOpen)); 18 //定义了一个静态文本框,并添加至wxFrame 19 tc = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); 20 //使窗口在屏幕上居中显示 21 Centre(); 22 } 23 24 void Openfile::OnOpen(wxCommandEvent & event) 25 { 26 //定义一个文件对话框wxFileDialog 27 wxFileDialog * openFileDialog = new wxFileDialog(this); 28 29 //如果文件选择成功 30 if(openFileDialog->ShowModal() == wxID_OK) 31 { 32 //获取文件名 33 wxString fileName = openFileDialog->GetPath(); 34 //将文件内容显示在静态文本框中 35 tc->LoadFile(fileName); 36 } 37 } 38 39 //声明应用程序 40 IMPLEMENT_APP(MyApp) 41 42 bool MyApp::OnInit() 43 { 44 Openfile * open = new Openfile(_T("Openfile")); 45 open->Show(true); 46 47 return true; 48 }
在我们的例子中,我们显示了一个打开文件的菜单选项和一个简单的多行文本控件。如果我们单击了打开文件的菜单选项,会显示一个wxFileDialog窗口,我们能够加载一些简单的文本文件到文本控件中。
tc = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
我们把文本文件加载在wxTextCtrl中
wxFileDialog * openFileDialog = new wxFileDialog(this);
这里我们创建了一个wxFileDialog,我们使用了默认的参数。(这个打开文件的对话框是一个默认的对话框)
1 if(openFileDialog->ShowModal() == wxID_OK) 2 { 3 wxString fileName = openFileDialog->GetPath(); 4 tc->LoadFile(fileName); 5 }
这里我们显示这个对话框,我们获得了一个选中的文件的路径名,并且把这个文件加载到文本控件中。
wxFontDialog
这是一个普通的字体选择对话框。
main.h
1 //字体对话框 2 //通过字体对话框,改变一个静态文本框中文字的字体样式 3 #include <wx/wx.h> 4 #include <wx/fontdlg.h> 5 6 class ChangeFont : public wxFrame 7 { 8 public: 9 ChangeFont(const wxString & title); 10 11 void OnOpen(wxCommandEvent & event); 12 //定义一个静态文本框 13 wxStaticText * st; 14 15 enum{ID_FONTDIALOG}; 16 }; 17 18 class MyApp : public wxApp 19 { 20 public: 21 virtual bool OnInit(); 22 };
main.cpp
1 #include "main.h" 2 3 ChangeFont::ChangeFont(const wxString & title) 4 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200)) 5 { 6 //定义一个面板放置在wxFrame中 7 wxPanel * panel = new wxPanel(this, wxID_ANY); 8 //定义菜单栏 9 wxMenuBar * menubar = new wxMenuBar; 10 //定义菜单项 11 wxMenu * file = new wxMenu; 12 file->Append(ID_FONTDIALOG, _T("&Change Font")); 13 //将菜单项添加值菜单栏 14 menubar->Append(file, _T("&File")); 15 //将菜单栏添加到wxFrame中 16 this->SetMenuBar(menubar); 17 //事件处理函数的动态关联 18 Connect(ID_FONTDIALOG, wxEVT_COMMAND_MENU_SELECTED, 19 wxCommandEventHandler(ChangeFont::OnOpen)); 20 //定义一个今天文本框,放置在Panel上 21 st = new wxStaticText(panel, wxID_ANY, _T("PingGe"), wxPoint(20, 20)); 22 //使窗口在屏幕上居中显示 23 Centre(); 24 } 25 26 void ChangeFont::OnOpen(wxCommandEvent & WXUNUSED(event)) 27 { 28 wxFontDialog * fontDialog = new wxFontDialog(this); 29 //如果字体对话框设置成功 30 if(fontDialog->ShowModal() == wxID_OK) 31 { 32 //按照字体对话框中对字体的设置,修改静态文本框中字体的样式 33 st->SetFont(fontDialog->GetFontData().GetChosenFont()); 34 } 35 } 36 //声明应用程序 37 IMPLEMENT_APP(MyApp) 38 39 bool MyApp::OnInit() 40 { 41 ChangeFont * change = new ChangeFont(_T("Change font")); 42 change->Show(true); 43 44 return true; 45 }
在这个例子中,我们通过一个设置字体对话框来改变一个静态文本控件的文字。
st = new wxStaticText(panel, wxID_ANY, _T("PingGe"), wxPoint(20, 20));
这里我们在panel上面显示了一段静态文本,我们将通过wxFontDialog改变它的字体。
1 wxFontDialog * fontDialog = new wxFontDialog(this); 2 if(fontDialog->ShowModal() == wxID_OK) 3 { 4 st->SetFont(fontDialog->GetFontData().GetChosenFont()); 5 }
在这几行代码中,我们显示了这个字体设置对话框,然后我们获得了选中的字体信息,最后我们用这个字体去改变我们早先创建的静态文本。
字体对话框效果展示:
一个自定义的对话框
在接下来的这个例子中,我们创建了一个自定义的对话框,一款图像编辑器可以改变一张图片的色深,为了提供这个功能,我们应该定义一个适当的对话框。
main.h
main.cpp
这个例子是一个基于对话框的程序,我们简单展示了如何制定一个自定义的对话框。
1 class CustomDialog : public wxDialog
一个基于wxDialog的自定义对话框。
1 wxStaticBox * st = new wxStaticBox(panel, wxID_ANY, _T("Colors"), wxPoint(5, 5), wxSize(240, 150)); 2 wxRadioButton * rb1 = new wxRadioButton(panel, wxID_ANY, _T("16 Colors"), wxPoint(15, 55));
注意:wxStaticBox这个组件必须在它所包含的组件之前定义,而且这些组件相互之间不能是父子关系,只能是兄弟关系。
1 ShowModal(); 2 Destroy();
我们调用ShowModal()方法显示这个对话框,Destroy()方法关闭并且清理这个对话框。
效果展示: