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

/***************************************************************
 * 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_
View Code
/***************************************************************
 * 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;
}
View Code
/***************************************************************
 * 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_
View Code
/***************************************************************
 * 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(2);
    SetStatusText(wxT("welcome to wxWidgets!"), 1);

    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();
}
View Code
/***************************************************************
 * 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_
View Code
/***************************************************************
 * 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, 0, wxALIGN_CENTRE_HORIZONTAL|wxALL, 5);
    //*)

    /**< 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, 0, wxALIGN_LEFT|wxALL, 5);

    /**< Spacer */
    boxSizer->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    /**< Label for the name text control */
    wxStaticText * nameLabel = new wxStaticText(this, wxID_STATIC, wxT("&Name:"),
                                                wxDefaultPosition, wxDefaultSize);
    boxSizer->Add(nameLabel, 0, wxALIGN_LEFT|wxALL, 5);

    /**< A text control for the user's name */
    wxTextCtrl * nameCtrl = new wxTextCtrl(this, ID_NAME, wxT("Emma"),
                                           wxDefaultPosition, wxDefaultSize);
    boxSizer->Add(nameCtrl, 0, wxGROW|wxALL, 5);

    //(*A horizontal box sizer to contain age,sex and vote
    wxBoxSizer * ageSexVoteBox = new wxBoxSizer(wxHORIZONTAL);
    boxSizer->Add(ageSexVoteBox, 0, wxGROW|wxALL, 5);
    //*)

    /**< Label for the age control */
    wxStaticText * ageLabel = new wxStaticText(this, wxID_STATIC, wxT("&Age"),
                                               wxDefaultPosition, wxDefaultSize);
    ageSexVoteBox->Add(ageLabel, 0, wxALIGN_CENTRE_VERTICAL|wxALL, 5);

    /**< A spin control for the user's age */
    wxSpinCtrl * ageSpin = new wxSpinCtrl(this, ID_AGE, wxEmptyString,
                                          wxDefaultPosition, wxSize(60, -1), wxSP_ARROW_KEYS, 0, 120, 25);
    ageSexVoteBox->Add(ageSpin, 0, wxALIGN_CENTRE_VERTICAL|wxALL, 5);

    /**< Label for the sex control */
    wxStaticText * sexLabel = new wxStaticText(this, wxID_STATIC, wxT("&Sex:"),
                                               wxDefaultPosition, wxDefaultSize);
    ageSexVoteBox->Add(sexLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    /**< Create the sex choice control */
    wxString sexStrings[] = {   wxT("Male"),
                                wxT("Female")
                            };
    wxChoice * sexChoice = new wxChoice(this, ID_SEX, wxDefaultPosition,
                                        wxSize(80, -1), WXSIZEOF(sexStrings), sexStrings);
    sexChoice->SetStringSelection(wxT("Female"));
    ageSexVoteBox->Add(sexChoice, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    /**< Add a spacer thar stretches to push the Vote control to the right */
    ageSexVoteBox->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxCheckBox * voteCheckBox = new wxCheckBox(this, ID_VOTE, wxT("&Vote"),
                                               wxDefaultPosition, wxDefaultSize);
    voteCheckBox->SetValue(true);
    ageSexVoteBox->Add(voteCheckBox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    /**< A dividing line before the OK and Cancel buttons */
    wxStaticLine * line = new wxStaticLine(this, wxID_STATIC,
                                           wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
    boxSizer->Add(line, 0, wxGROW|wxALL, 5);

    //(*A horizontal box sizer to contain Reset,OK,Cancel and Help
    wxBoxSizer * okCancelBox = new wxBoxSizer(wxHORIZONTAL);
    boxSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
    //*)

    /**< The Reset button */
    wxButton * reset = new wxButton(this, ID_ON_RESET, wxT("&Reset"),
                                    wxDefaultPosition, wxDefaultSize);
    okCancelBox->Add(reset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    /**< The OK button */
    wxButton * ok = new wxButton(this, ID_ON_OK, wxT("&OK"),
                                 wxDefaultPosition, wxDefaultSize);
    okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    /**< The Cancel button */
    wxButton * cancel = new wxButton(this, ID_ON_CANCEL, wxT("&Cancel"),
                                     wxDefaultPosition, wxDefaultSize);
    okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    /**< The Help button */
    wxButton * help = new wxButton(this, ID_ON_HELP, wxT("&Help"),
                                   wxDefaultPosition, wxDefaultSize);
    okCancelBox->Add(help, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
}


/**< 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() < 18)
    {
        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);
}
View Code
/***************************************************************
 * 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(0), __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 != 0)
        {
            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
View Code

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

posted @ 2013-11-23 10:50  瓶哥  Views(1197)  Comments(0Edit  收藏  举报