原文: http://zetcode.com/gui/wxwidgets/dialogs/

对话框窗口或对话框是大多数现代 GUI 应用必不可少的部分。 对话被定义为两个或更多人之间的对话。 在计算机应用中,对话框是一个窗口,用于与应用“对话”。 对话框用于输入数据,修改数据,更改应用设置等。对话框是用户与计算机程序之间进行通信的重要手段。

对话框本质上有两种:预定义对话框和自定义对话框。

预定义对话框

预定义对话框是 wxWidgets 工具包中可用的对话框。 这些是用于常见编程任务的对话框,例如显示文本,接收输入,加载和保存文件等。它们可以节省程序员的时间,并通过使用某些标准行为来增强功能。

MessageDialog

消息对话框用于向用户显示消息。 它们是可定制的。 我们可以更改将在对话框中显示的图标和按钮。

Messages.h

  1. #include <wx/wx.h>
  2. class Messages : public wxFrame
  3. {
  4. public:
  5. Messages(const wxString& title);
  6. void ShowMessage1(wxCommandEvent & event);
  7. void ShowMessage2(wxCommandEvent & event);
  8. void ShowMessage3(wxCommandEvent & event);
  9. void ShowMessage4(wxCommandEvent & event);
  10. };
  11. const int ID_INFO = 1;
  12. const int ID_ERROR = 2;
  13. const int ID_QUESTION = 3;
  14. const int ID_ALERT = 4;

Messages.cpp

  1. #include "Messages.h"
  2. Messages::Messages(const wxString& title)
  3. : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(210, 110))
  4. {
  5. wxPanel *panel = new wxPanel(this, wxID_ANY);
  6. wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
  7. wxGridSizer *gs = new wxGridSizer(2, 2, 2, 2);
  8. wxButton *btn1 = new wxButton(panel, ID_INFO, wxT("Info"));
  9. wxButton *btn2 = new wxButton(panel, ID_ERROR, wxT("Error"));
  10. wxButton *btn3 = new wxButton(panel, ID_QUESTION, wxT("Question"));
  11. wxButton *btn4 = new wxButton(panel, ID_ALERT, wxT("Alert"));
  12. Connect(ID_INFO, wxEVT_COMMAND_BUTTON_CLICKED,
  13. wxCommandEventHandler(Messages::ShowMessage1));
  14. Connect(ID_ERROR, wxEVT_COMMAND_BUTTON_CLICKED,
  15. wxCommandEventHandler(Messages::ShowMessage2));
  16. Connect(ID_QUESTION, wxEVT_COMMAND_BUTTON_CLICKED,
  17. wxCommandEventHandler(Messages::ShowMessage3));
  18. Connect(ID_ALERT, wxEVT_COMMAND_BUTTON_CLICKED,
  19. wxCommandEventHandler(Messages::ShowMessage4));
  20. gs->Add(btn1, 1, wxEXPAND);
  21. gs->Add(btn2, 1);
  22. gs->Add(btn3, 1);
  23. gs->Add(btn4, 1);
  24. hbox->Add(gs, 0, wxALL, 15);
  25. panel->SetSizer(hbox);
  26. Center();
  27. }
  28. void Messages::ShowMessage1(wxCommandEvent& event)
  29. {
  30. wxMessageDialog *dial = new wxMessageDialog(NULL,
  31. wxT("Download completed"), wxT("Info"), wxOK);
  32. dial->ShowModal();
  33. }
  34. void Messages::ShowMessage2(wxCommandEvent& event)
  35. {
  36. wxMessageDialog *dial = new wxMessageDialog(NULL,
  37. wxT("Error loading file"), wxT("Error"), wxOK | wxICON_ERROR);
  38. dial->ShowModal();
  39. }
  40. void Messages::ShowMessage3(wxCommandEvent& event)
  41. {
  42. wxMessageDialog *dial = new wxMessageDialog(NULL,
  43. wxT("Are you sure to quit?"), wxT("Question"),
  44. wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
  45. dial->ShowModal();
  46. }
  47. void Messages::ShowMessage4(wxCommandEvent& event)
  48. {
  49. wxMessageDialog *dial = new wxMessageDialog(NULL,
  50. wxT("Unallowed operation"), wxT("Exclamation"),
  51. wxOK | wxICON_EXCLAMATION);
  52. dial->ShowModal();
  53. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "Messages.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. Messages *msgs = new Messages(wxT("Messages"));
  7. msgs->Show(true);
  8. return true;
  9. }

在我们的示例中,我们创建了四个按钮并将它们放入网格大小调整器中。 这些按钮将显示四个不同的对话框窗口。 我们通过指定不同的样式标志来创建它们。

  1. wxMessageDialog *dial = new wxMessageDialog(NULL,
  2. wxT("Error loading file"), wxT("Error"), wxOK | wxICON_ERROR);
  3. dial->ShowModal();

消息对话框的创建很简单。 通过提供NULL作为父级,我们将对话框设置为顶级窗口。 这两个字符串提供了消息文本和对话框标题。 通过指定wxOKwxICON_ERROR标志,我们显示一个 OK 按钮和一个错误图标。 为了在屏幕上显示对话框,我们调用ShowModal()方法。

wxWidgets 中的对话框 - 图1

wxWidgets 中的对话框 - 图2

wxWidgets 中的对话框 - 图3

wxWidgets 中的对话框 - 图4

wxFileDialog

这是打开和保存文件的常用对话框。

openfile.h

  1. #include <wx/wx.h>
  2. class Openfile : public wxFrame
  3. {
  4. public:
  5. Openfile(const wxString& title);
  6. void OnOpen(wxCommandEvent& event);
  7. wxTextCtrl *tc;
  8. };

openfile.cpp

  1. #include "openfile.h"
  2. Openfile::Openfile(const wxString & title)
  3. : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
  4. {
  5. wxMenuBar *menubar = new wxMenuBar;
  6. wxMenu *file = new wxMenu;
  7. file->Append(wxID_OPEN, wxT("&Open"));
  8. menubar->Append(file, wxT("&File"));
  9. SetMenuBar(menubar);
  10. Connect(wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED,
  11. wxCommandEventHandler(Openfile::OnOpen));
  12. tc = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1),
  13. wxSize(-1, -1), wxTE_MULTILINE);
  14. Center();
  15. }
  16. void Openfile::OnOpen(wxCommandEvent& event)
  17. {
  18. wxFileDialog * openFileDialog = new wxFileDialog(this);
  19. if (openFileDialog->ShowModal() == wxID_OK){
  20. wxString fileName = openFileDialog->GetPath();
  21. tc->LoadFile(fileName);
  22. }
  23. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "openfile.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. Openfile *open = new Openfile(wxT("Openfile"));
  7. open->Show(true);
  8. return true;
  9. }

在我们的示例中,我们显示一个打开文件菜单项和一个简单的多行文本控件。 如果单击打开文件菜单项,则会显示wxFileDialog。 我们可以将一些简单的文本文件加载到文本控件中。

  1. tc = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1),
  2. wxSize(-1, -1), wxTE_MULTILINE);

我们将文本文件加载到此文本控件中。

  1. wxFileDialog * openFileDialog = new wxFileDialog(this);

在这里,我们创建一个wxFileDialog。 我们使用默认参数。 (打开文件对话框是默认对话框。)

  1. if (openFileDialog->ShowModal() == wxID_OK){
  2. wxString fileName = openFileDialog->GetPath();
  3. tc->LoadFile(fileName);
  4. }

在这里,我们显示对话框。 我们获得选定的文件名,并将文件加载到文本控件中。

wxWidgets 中的对话框 - 图5

图:Linux 上的wxFileDialog

wxFontDialog

这是选择字体的常用对话框。

fontdialog.h

  1. #include <wx/wx.h>
  2. class ChangeFont : public wxFrame
  3. {
  4. public:
  5. ChangeFont(const wxString& title);
  6. void OnOpen(wxCommandEvent& event);
  7. wxStaticText *st;
  8. };
  9. const int ID_FONTDIALOG = 1;

fontdialog.cpp

  1. #include <wx/fontdlg.h>
  2. #include "fontdialog.h"
  3. ChangeFont::ChangeFont(const wxString & title)
  4. : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
  5. {
  6. wxPanel *panel = new wxPanel(this, -1);
  7. wxMenuBar *menubar = new wxMenuBar;
  8. wxMenu *file = new wxMenu;
  9. file->Append(ID_FONTDIALOG, wxT("&Change font"));
  10. menubar->Append(file, wxT("&File"));
  11. SetMenuBar(menubar);
  12. Connect(ID_FONTDIALOG, wxEVT_COMMAND_MENU_SELECTED,
  13. wxCommandEventHandler(ChangeFont::OnOpen));
  14. st = new wxStaticText(panel, wxID_ANY, wxT("The Agoge"),
  15. wxPoint(20, 20));
  16. Center();
  17. }
  18. void ChangeFont::OnOpen(wxCommandEvent& WXUNUSED(event))
  19. {
  20. wxFontDialog *fontDialog = new wxFontDialog(this);
  21. if (fontDialog->ShowModal() == wxID_OK) {
  22. st->SetFont(fontDialog->GetFontData().GetChosenFont());
  23. }
  24. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "fontdialog.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. ChangeFont *change = new ChangeFont(wxT("Change font"));
  7. change->Show(true);
  8. return true;
  9. }

在此示例中,我们将更改静态文本示例的字体。

  1. st = new wxStaticText(panel, wxID_ANY, wxT("The Agoge"),
  2. wxPoint(20, 20));

在这里,我们在面板上显示静态文本。 我们将使用wxFontDialog更改其字体。

  1. wxFontDialog *fontDialog = new wxFontDialog(this);
  2. if (fontDialog->ShowModal() == wxID_OK) {
  3. st->SetFont(fontDialog->GetFontData().GetChosenFont());
  4. }

在这些代码行中,我们显示字体对话框。 然后我们得到选择的字体。 最后,我们更改之前创建的静态文本的字体。

wxWidgets 中的对话框 - 图6

图:字体对话框

自定义对话框

在下一个示例中,我们创建一个自定义对话框。 图像编辑应用可以更改图片的颜色深度。 为了提供这种功能,我们可以创建一个合适的自定义对话框。

customdialog.h

  1. #include <wx/wx.h>
  2. class CustomDialog : public wxDialog
  3. {
  4. public:
  5. CustomDialog(const wxString& title);
  6. };

customdialog.cpp

  1. #include "customdialog.h"
  2. CustomDialog::CustomDialog(const wxString & title)
  3. : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(250, 230))
  4. {
  5. wxPanel *panel = new wxPanel(this, -1);
  6. wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  7. wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
  8. wxStaticBox *st = new wxStaticBox(panel, -1, wxT("Colors"),
  9. wxPoint(5, 5), wxSize(240, 150));
  10. wxRadioButton *rb = new wxRadioButton(panel, -1,
  11. wxT("256 Colors"), wxPoint(15, 30), wxDefaultSize, wxRB_GROUP);
  12. wxRadioButton *rb1 = new wxRadioButton(panel, -1,
  13. wxT("16 Colors"), wxPoint(15, 55));
  14. wxRadioButton *rb2 = new wxRadioButton(panel, -1,
  15. wxT("2 Colors"), wxPoint(15, 80));
  16. wxRadioButton *rb3 = new wxRadioButton(panel, -1,
  17. wxT("Custom"), wxPoint(15, 105));
  18. wxTextCtrl *tc = new wxTextCtrl(panel, -1, wxT(""),
  19. wxPoint(95, 105));
  20. wxButton *okButton = new wxButton(this, -1, wxT("Ok"),
  21. wxDefaultPosition, wxSize(70, 30));
  22. wxButton *closeButton = new wxButton(this, -1, wxT("Close"),
  23. wxDefaultPosition, wxSize(70, 30));
  24. hbox->Add(okButton, 1);
  25. hbox->Add(closeButton, 1, wxLEFT, 5);
  26. vbox->Add(panel, 1);
  27. vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);
  28. SetSizer(vbox);
  29. Centre();
  30. ShowModal();
  31. Destroy();
  32. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "customdialog.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. CustomDialog *custom = new CustomDialog(wxT("CustomDialog"));
  7. custom->Show(true);
  8. return true;
  9. }

本示例是基于对话框的应用。 我们说明了如何创建自定义对话框。

  1. class CustomDialog : public wxDialog

自定义对话框基于wxDialog类。

  1. wxStaticBox *st = new wxStaticBox(panel, -1, wxT("Colors"),
  2. wxPoint(5, 5), wxSize(240, 150));
  3. wxRadioButton *rb = new wxRadioButton(panel, -1,
  4. wxT("256 Colors"), wxPoint(15, 30), wxDefaultSize, wxRB_GROUP);

请注意,必须先创建wxStaticBox小部件,然后再包含该小部件,并且这些小部件应该是静态框的同级,而不是子级。

  1. ShowModal();
  2. Destroy();

为了在屏幕上显示对话框,我们调用ShowModal()方法。 要从内存中清除对话框,我们调用Destroy()方法。

wxWidgets 中的对话框 - 图7

图:自定义对话框

wxWidgets 教程的这一部分专门用于对话框。