wxWidgets一个界面与数据分离的简单例子

时间:2021-01-05 11:26:04
/***************************************************************
* Name: MyApp.h
* Purpose: Defines MyApp Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-10-19
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ #ifndef MYAPP_H_
#define MYAPP_H_ //(*Headers(MyApp)
#include <wx/app.h>
//*) class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
DECLARE_APP(MyApp) #endif // MYAPP_H_
/***************************************************************
* Name: MyApp.cpp
* Purpose: Code for MyApp Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-10-19
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ //(*Headers(MyApp)
#include <wx/wx.h>
#include "MyApp.h"
#include "MyFrame.h"
//*) IMPLEMENT_APP(MyApp) bool MyApp::OnInit()
{
/**< Create the main application window */
MyFrame * frame = new MyFrame(wxT("PersonalRecordDialog Demo")); frame->Show(true); /**< Start the event loop */
return wxOK;
}
/***************************************************************
* Name: MyFrame.h
* Purpose: Defines MyFrame Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-10-19
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ #ifndef MYFRAME_H_
#define MYFRAME_H_ //(*Headers(MyFrame)
#include <wx/wx.h>
//*) class MyFrame : public wxFrame
{
DECLARE_CLASS(MyFrame) DECLARE_EVENT_TABLE() public:
MyFrame(const wxString & title);
virtual ~MyFrame() {} void CreateControls(); //(*Handlers(MyFrame)
void OnAbout (wxCommandEvent & event);
void OnQuit (wxCommandEvent & event);
void OnShowDialog (wxCommandEvent & event);
//*) protected:
//(*Identifiers(MyFrame)
enum{ID_SHOW_DIALOG};
//*)
}; #endif // MYFRAME_H_
/***************************************************************
* Name: MyFrame.cpp
* Purpose: Code for MyFrame Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-10-19
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ //(*Headers(MyFrame)
#include <wx/wx.h>
#include <wx/popupwin.h>
#include <wx/notebook.h>
#include "MyFrame.h"
#include "personalRecord.h"
#include "wx.xpm"
//*) IMPLEMENT_CLASS(MyFrame, wxFrame) BEGIN_EVENT_TABLE(MyFrame, wxFrame)
//(*EventTable(MyFrame)
EVT_MENU (wxID_ABOUT, MyFrame::OnAbout)
EVT_MENU (wxID_EXIT, MyFrame::OnQuit)
EVT_MENU (ID_SHOW_DIALOG, MyFrame::OnShowDialog)
//*)
END_EVENT_TABLE() MyFrame::MyFrame(const wxString & title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE)
{
/**< Set the frame icon */
SetIcon(wxIcon(wx_xpm)); /**< Create a menu bar */
wxMenu * fileMenu = new wxMenu;
wxMenu * helpMenu = new wxMenu; helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"), wxT("Show about dialog"));
fileMenu->Append(ID_SHOW_DIALOG, wxT("&Show Personal Record Dialog..."), wxT("Show Personal Record Dialog"));
fileMenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"), wxT("Quit this program")); /**< Now append the freshly created menu to the menu bar... */
wxMenuBar * menuBar = new wxMenuBar();
menuBar->Append(fileMenu, wxT("&File"));
menuBar->Append(helpMenu, wxT("&Help")); /**< ... and attach this menu bar to the frame */
SetMenuBar(menuBar); CreateStatusBar();
SetStatusText(wxT("welcome to wxWidgets!"), ); CreateControls();
} void MyFrame::CreateControls()
{ } void MyFrame::OnAbout(wxCommandEvent & event)
{
wxString msg;
msg.Printf(wxT("PersonalRecordDialog example, built with wxWidgets %s"), wxVERSION_STRING); wxMessageBox(msg, wxT("About this program"), wxOK|wxICON_INFORMATION, this);
} void MyFrame::OnQuit(wxCommandEvent & event)
{
/**< Destroy the frame */
Close(wxOK);
} void MyFrame::OnShowDialog(wxCommandEvent & event)
{
PersonalRecordDialog dialog(this, wxID_ANY, wxT("Personal Record"),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
dialog.ShowModal();
}
/***************************************************************
* Name: PersonalRecord.h
* Purpose: Defines PersonalRecordDialog Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-10-19
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ #ifndef PERSONALRECORD_H_
#define PERSONALRECORD_H_ //(*Headers(PersonalRecordDialog)
#include <wx/spinctrl.h>
#include <wx/statline.h>
#include "Data.h"
//*) class PersonalRecordDialog : public wxDialog
{
DECLARE_CLASS(PersonalRecordDialog) DECLARE_EVENT_TABLE() public:
PersonalRecordDialog(); PersonalRecordDialog( wxWindow * parent,
wxWindowID id = ID_PERSONAL_RECORD,
const wxString & caption = wxT("Personal Record"),
const wxPoint & post = wxDefaultPosition,
const wxSize & size = wxDefaultSize,
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU
); /**< Member initialisation */
void Init(); /**< Creation */
bool Create( wxWindow * parent,
wxWindowID id = ID_PERSONAL_RECORD,
const wxString & caption = wxT("Personal Record"),
const wxPoint & post = wxDefaultPosition,
const wxSize & size = wxDefaultSize,
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU
); void CreateControls(); void SetDialogValidators(); void SetDialogHelp(); //(*Handlers(PersonalRecordDialog)
void OnVoteUpdate(wxUpdateUIEvent & event);
void OnResetClick(wxCommandEvent & event);
void OnOkClick(wxCommandEvent & event);
void OnCancelClick(wxCommandEvent & event);
void OnHelpClick(wxCommandEvent & event);
//*) protected:
//(*Identifiers(PersonalRecordDialog)
enum{ID_PERSONAL_RECORD,
ID_NAME,
ID_AGE,
ID_SEX,
ID_VOTE,
ID_ON_RESET,
ID_ON_OK,
ID_ON_CANCEL,
ID_ON_HELP};
//*) private:
Data person;
}; #endif //#define _PERSONALRECORD_H_
/***************************************************************
* Name: PersonalRecord.cpp
* Purpose: Code for PersonalRecordDialog Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-10-19
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ //(*Headers(PersonalRecordDialog)
#include "wx/wx.h"
#include "wx/valgen.h" // for TransferDataToWindow()
#include "wx/valtext.h" // for wxTextValidator()
#include "wx/cshelp.h"
#include "PersonalRecord.h"
//*) IMPLEMENT_CLASS(PersonalRecordDialog, wxDialog) BEGIN_EVENT_TABLE(PersonalRecordDialog, wxDialog)
//(*EventTable(PersonalRecordDialog)
EVT_UPDATE_UI (ID_VOTE, PersonalRecordDialog::OnVoteUpdate)
EVT_BUTTON (ID_ON_RESET, PersonalRecordDialog::OnResetClick)
EVT_BUTTON (ID_ON_OK, PersonalRecordDialog::OnOkClick)
EVT_BUTTON (ID_ON_CANCEL, PersonalRecordDialog::OnCancelClick)
EVT_BUTTON (ID_ON_HELP, PersonalRecordDialog::OnHelpClick)
//*)
END_EVENT_TABLE() PersonalRecordDialog::PersonalRecordDialog()
{
Init();
} PersonalRecordDialog::PersonalRecordDialog( wxWindow * parent,
wxWindowID id,
const wxString & caption,
const wxPoint & pos,
const wxSize & size,
long style
)
{
Init();
Create(parent, id, caption, pos, size, style);
} /**< Initialisation */
void PersonalRecordDialog::Init(void)
{
person.Read();
} bool PersonalRecordDialog::Create( wxWindow * parent,
wxWindowID id,
const wxString & caption,
const wxPoint & pos,
const wxSize & size,
long style
)
{
/**< We have to set extra styles before creating the dialog */
SetExtraStyle(wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP); if(!wxDialog::Create(parent, id, caption, pos, size, style))
{
return false;
} CreateControls();
SetDialogHelp();
SetDialogValidators(); /**< This fits the dialog to the minimum size dictated by the sizer */
GetSizer()->Fit(this); /**< This ensures that the dialog cannot be sized smaller than the minimum size */
GetSizer()->SetSizeHints(this); //Centre the dialog on the parent or screen(if none parent)
Centre(); return true;
} /**< Control creation for PersonalRecordDialog */
void PersonalRecordDialog::CreateControls(void)
{
//(*A top-level sizer
wxBoxSizer * topSizer = new wxBoxSizer(wxVERTICAL);
this->SetSizer(topSizer);
//*) //(*A second box sizer to give more space around the controls
wxBoxSizer * boxSizer = new wxBoxSizer(wxVERTICAL);
topSizer->Add(boxSizer, , wxALIGN_CENTRE_HORIZONTAL|wxALL, );
//*) /**< A friendly message */
wxStaticText * descr = new wxStaticText(this, wxID_STATIC,
wxT("Please enter your name, age and sex, and specify whether you wish to\nvote in a general election."),
wxDefaultPosition, wxDefaultSize);
boxSizer->Add(descr, , wxALIGN_LEFT|wxALL, ); /**< Spacer */
boxSizer->Add(, , , wxALIGN_CENTER_HORIZONTAL|wxALL, ); /**< Label for the name text control */
wxStaticText * nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"),
wxDefaultPosition, wxDefaultSize);
boxSizer->Add(nameLabel, , wxALIGN_LEFT|wxALL, ); /**< A text control for the user's name */
wxTextCtrl * nameCtrl = new wxTextCtrl(this, ID_NAME, wxT("Emma"),
wxDefaultPosition, wxDefaultSize);
boxSizer->Add(nameCtrl, , wxGROW|wxALL, ); //(*A horizontal box sizer to contain age,sex and vote
wxBoxSizer * ageSexVoteBox = new wxBoxSizer(wxHORIZONTAL);
boxSizer->Add(ageSexVoteBox, , wxGROW|wxALL, );
//*) /**< Label for the age control */
wxStaticText * ageLabel = new wxStaticText(this, wxID_STATIC, wxT("&Age"),
wxDefaultPosition, wxDefaultSize);
ageSexVoteBox->Add(ageLabel, , wxALIGN_CENTRE_VERTICAL|wxALL, ); /**< A spin control for the user's age */
wxSpinCtrl * ageSpin = new wxSpinCtrl(this, ID_AGE, wxEmptyString,
wxDefaultPosition, wxSize(, -), wxSP_ARROW_KEYS, , , );
ageSexVoteBox->Add(ageSpin, , wxALIGN_CENTRE_VERTICAL|wxALL, ); /**< Label for the sex control */
wxStaticText * sexLabel = new wxStaticText(this, wxID_STATIC, wxT("&Sex:"),
wxDefaultPosition, wxDefaultSize);
ageSexVoteBox->Add(sexLabel, , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< Create the sex choice control */
wxString sexStrings[] = { wxT("Male"),
wxT("Female")
};
wxChoice * sexChoice = new wxChoice(this, ID_SEX, wxDefaultPosition,
wxSize(, -), WXSIZEOF(sexStrings), sexStrings);
sexChoice->SetStringSelection(wxT("Female"));
ageSexVoteBox->Add(sexChoice, , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< Add a spacer thar stretches to push the Vote control to the right */
ageSexVoteBox->Add(, , , wxALIGN_CENTER_VERTICAL|wxALL, ); wxCheckBox * voteCheckBox = new wxCheckBox(this, ID_VOTE, wxT("&Vote"),
wxDefaultPosition, wxDefaultSize);
voteCheckBox->SetValue(true);
ageSexVoteBox->Add(voteCheckBox, , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< A dividing line before the OK and Cancel buttons */
wxStaticLine * line = new wxStaticLine(this, wxID_STATIC,
wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
boxSizer->Add(line, , wxGROW|wxALL, ); //(*A horizontal box sizer to contain Reset,OK,Cancel and Help
wxBoxSizer * okCancelBox = new wxBoxSizer(wxHORIZONTAL);
boxSizer->Add(okCancelBox, , wxALIGN_CENTER_HORIZONTAL|wxALL, );
//*) /**< The Reset button */
wxButton * reset = new wxButton(this, ID_ON_RESET, wxT("&Reset"),
wxDefaultPosition, wxDefaultSize);
okCancelBox->Add(reset, , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< The OK button */
wxButton * ok = new wxButton(this, ID_ON_OK, wxT("&OK"),
wxDefaultPosition, wxDefaultSize);
okCancelBox->Add(ok, , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< The Cancel button */
wxButton * cancel = new wxButton(this, ID_ON_CANCEL, wxT("&Cancel"),
wxDefaultPosition, wxDefaultSize);
okCancelBox->Add(cancel, , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< The Help button */
wxButton * help = new wxButton(this, ID_ON_HELP, wxT("&Help"),
wxDefaultPosition, wxDefaultSize);
okCancelBox->Add(help, , wxALIGN_CENTER_VERTICAL|wxALL, );
} /**< Set the validators for the dialog controls */
void PersonalRecordDialog::SetDialogValidators(void)
{
FindWindow(ID_NAME)->SetValidator(wxTextValidator(wxFILTER_ALPHA, person.GetName())); FindWindow(ID_AGE)->SetValidator(wxGenericValidator(person.GetAge())); FindWindow(ID_SEX)->SetValidator(wxGenericValidator(person.GetSex())); FindWindow(ID_VOTE)->SetValidator(wxGenericValidator(person.GetVote()));
} //Sets the help text for the dialog controls
void PersonalRecordDialog::SetDialogHelp(void)
{
wxString nameHelp = wxT("Enter your full name.");
wxString ageHelp = wxT("Specify your age");
wxString sexHelp = wxT("Specify your gender, male or female.");
wxString voteHelp = wxT("Check this if you wish to vote."); FindWindow(ID_NAME)->SetHelpText(nameHelp);
FindWindow(ID_NAME)->SetToolTip(nameHelp); FindWindow(ID_AGE)->SetHelpText(ageHelp);
FindWindow(ID_AGE)->SetToolTip(ageHelp); FindWindow(ID_SEX)->SetHelpText(sexHelp);
FindWindow(ID_SEX)->SetToolTip(sexHelp); FindWindow(ID_VOTE)->SetHelpText(voteHelp);
FindWindow(ID_VOTE)->SetToolTip(voteHelp);
} /**< wxEVT_UPDATE_UI event handler for ID_CHECKBOX */
void PersonalRecordDialog::OnVoteUpdate(wxUpdateUIEvent & event)
{
wxSpinCtrl * ageCtrl = (wxSpinCtrl*)FindWindow(ID_AGE); if(ageCtrl->GetValue() < )
{
event.Enable(false);
event.Check(false);
}
else
{
event.Enable(true);
}
} /**< wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RESET */
void PersonalRecordDialog::OnResetClick(wxCommandEvent & event)
{
Init();
TransferDataToWindow();
} void PersonalRecordDialog::OnOkClick(wxCommandEvent & event)
{
TransferDataFromWindow();
person.Save();
this->Destroy();
} void PersonalRecordDialog::OnCancelClick(wxCommandEvent & event)
{
this->Destroy();
} void PersonalRecordDialog::OnHelpClick(wxCommandEvent & event)
{
wxString helpText = wxT("Please enter your full name, age and gender.\n")
wxT("Also indicate your willingness to vote in general elections.\n\n")
wxT("No non-alphabetical characters are allowed in the name field.\n")
wxT("Try to be honest about your age."); wxMessageBox(helpText, wxT("Personal Record Dialog Help"), wxOK|wxICON_INFORMATION, this);
}
/***************************************************************
* Name: Data.h
* Purpose: Defines Data Class
* Author: PingGe (414236069@qq.com)
* Created: 2013-11-22
* Copyright: PingGe (http://www.cnblogs.com/pingge/)
* License:
**************************************************************/ #ifndef DATA_H
#define DATA_H //(*Headers(Data)
#include <wx/wx.h>
#include <wx/file.h>
//*) class Data
{
public:
Data() : __name(wxEmptyString), __age(), __sex(MALE), __vote(wxNO) {}
virtual ~Data() {} //(*Set(Data)
void SetName(const wxString & name) {__name = name;}
void SetAge(const int & age) {__age = age;}
void SetSex(const bool & sex) {__sex = sex;}
void SetVote(const bool & vote) {__vote = vote;}
//*) //(*Get(Data)
wxString * GetName() {return &__name;}
int * GetAge() {return &__age;}
int * GetSex() {return &__sex;}
bool * GetVote() {return &__vote;}
//*) void Save() const
{
wxFile fout(wxT("person.txt"), wxFile::write);
size_t len = __name.length();
fout.Write(&len, sizeof(size_t)); fout.Write(__name);
fout.Write(&__age, sizeof(__age));
fout.Write(&__sex, sizeof(__sex));
fout.Write(&__vote, sizeof(__vote));
fout.Close();
}
void Read()
{
wxFile fin(wxT("person.txt"), wxFile::read); size_t filesize;
fin.Read(&filesize, sizeof(size_t));
if(filesize != )
{
char * buf = new char[filesize];
fin.Read((void*)buf, filesize);
__name = wxString::From8BitData(buf);
}
else
{
__name = wxEmptyString;
} fin.Read(&__age, sizeof(__age));
fin.Read(&__sex, sizeof(__sex));
fin.Read(&__vote, sizeof(__vote));
fin.Close();
} private:
enum{MALE, FEMALE}; wxString __name;
int __age;
int __sex;
bool __vote;
}; #endif // DATA_H

由于本人水平有限,有些地方写的不好,望多多指教