1. 程式人生 > >wxWidget入門(七)

wxWidget入門(七)

這一期講一講自定義對話方塊

如下圖所示是這一期的對話方塊樣式,一個簡單投票對話方塊

要求如下:

  1. 介面設計規整,簡潔
  2. 按鈕實現對應功能
  3. 控制元件幫助提示
  4. 投票要求:小於18歲不能投票,投票欄變灰色。

①根據任務要求,列出類框架:

class PersonalRecordDialog : public wxDialog
{
public:
	PersonalRecordDialog(const wxString & title);
	//按鈕對應事件
	void OnOk(wxCommandEvent & event);
	void OnReset(wxCommandEvent & event);
	void OnCancel(wxCommandEvent & event);
	void OnHelp(wxCommandEvent & event);

private:
	wxString m_name; //參選人名
	int m_age;       //參選人年齡
	int m_sex;       //參選人性別
	bool m_vote;     //是否投票
private:
	bool TransferDataToWindow();    //將資料顯示到對應控制元件
	bool TransferDataFromWindow();  //獲取控制元件資料
	void Init();                    //初始化對話方塊
	void OnVoteUpdate(wxUpdateUIEvent & event);//控制18歲以下不能投票
	void SetDialogHelp();            //設定相關控制元件提示
public:
	void SetName(const wxString &name) {m_name = name;}
	wxString GetName() const {return m_name;}

	void SetAge(int age) {m_age = age;}
	int GetAge() const {return m_age;}

	void SetSex(bool sex) {sex ? m_sex = 1 : m_sex = 0;}
	bool GetSex() const {return m_sex == 1;}

	void SetVote(bool vote) {m_vote = vote;}
	bool GetVote() const {return m_vote;}
};

②根據框架編寫相應內容:

1、構造畫出對話方塊介面

PersonalRecordDialog::PersonalRecordDialog(const wxString & title)
	:wxDialog(NULL, -1, title, wxPoint(-1, -1), wxSize(400, 240))
{
    //設定底部畫布
	wxPanel * panel = new wxPanel(this, -1);
    //設定佈局 為垂直
	wxBoxSizer * vbox = new wxBoxSizer(wxVERTICAL);
    //說明標籤控制元件
	wxStaticText * t = new wxStaticText(panel, -1, 
		wxT("Please enter your name, age and sex, and specify whether you \nwish to vote in a general election"));
	vbox->Add(t, 0, wxALIGN_LEFT | wxALL, 5);//新增到佈局 左對齊 四周距離5
	vbox->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);//新增空行
	wxStaticText *t_name = new wxStaticText(panel, -1,//名字標籤控制元件
		wxT("Name"));
	vbox->Add(t_name, 0, wxALIGN_LEFT | wxALL, 5);
	wxTextCtrl * tc = new wxTextCtrl(panel, ID_NAME, wxT(""));//名字輸入框
	vbox->Add(tc, 0, wxALIGN_LEFT | wxALL, 5);

	wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
	wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL);

	wxStaticText * t_age = new wxStaticText(panel, -1,
		wxT("&Age"));
    //選擇年齡控制元件 範圍0 ~ 120 初始化為25
	wxSpinCtrl * spin = new wxSpinCtrl(panel, ID_SAGE ,wxEmptyString,
		wxDefaultPosition, wxSize(60, -1), wxSP_ARROW_KEYS, 0, 120, 25);//年齡選擇框
	wxStaticText * t_sex = new wxStaticText(panel, -1,
		wxT("&Sex"));
    //選擇性別控制元件
	wxString sexStrings[] = {
		wxT("Male"),
		wxT("Female")
	};
	wxChoice *sexChoice = new wxChoice(panel, ID_SEX, wxDefaultPosition,
		wxSize(80, -1), WXSIZEOF(sexStrings), sexStrings, 0);//性別選擇
    //投票勾選框
    wxCheckBox * vote = new wxCheckBox(panel, ID_VOTE, wxT("&Vote"));//投票選擇
	vote->SetValue(true);
	hbox1->Add(t_age, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
	hbox1->Add(spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
	hbox1->Add(t_sex, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
	hbox1->Add(sexChoice, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
	hbox1->Add(100, 5, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
	hbox1->Add(vote, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
	vbox->Add(hbox1);
    //新增一條分割線
	wxStaticLine * line = new wxStaticLine(panel, -1, wxDefaultPosition,
		wxDefaultSize, wxLI_HORIZONTAL);
	vbox->Add(line, 0, wxGROW | wxALL, 5);

	wxButton * btn1 = new wxButton(panel, wxID_RESET, wxT("&Reset"));
	wxButton * btn2 = new wxButton(panel, wxID_OK, wxT("&Ok"));
	wxButton * btn3 = new wxButton(panel, wxID_CANCEL, wxT("&Cancel"));
	wxButton * btn4 = new wxButton(panel, -1, wxT("&Help"));
	Connect(wxID_RESET, wxEVT_COMMAND_BUTTON_CLICKED,
		wxCommandEventHandler(PersonalRecordDialog::OnReset));
	Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
		wxCommandEventHandler(PersonalRecordDialog::OnOk));
	Connect(wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED,
		wxCommandEventHandler(PersonalRecordDialog::OnCancel));
    //連線介面更新事件,為了實現18歲以下不能投票
	Connect(ID_VOTE, wxEVT_UPDATE_UI,
		wxUpdateUIEventHandler(PersonalRecordDialog::OnVoteUpdate));
	
	hbox2->Add(btn1, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 5);
	hbox2->Add(btn2, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 5);
	hbox2->Add(btn3, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 5);
	hbox2->Add(btn4, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 5);
	vbox->Add(hbox2);
	panel->SetSizer(vbox);
	SetDialogHelp();//新增幫助設定(成員函式)
	Centre();
}

 

 2、相應按鈕事件 

void PersonalRecordDialog::OnOk(wxCommandEvent & event)
{
    //Validate 檢測控制元件內容是否符合控制元件要求 
	if(Validate() && TransferDataFromWindow())
	{
		if(IsModal())//如果是模式對話方塊
			EndModal(wxID_OK);//結束對話方塊(隱藏)並且返回wxID_OK
		else//不是模式對話方塊
		{
			SetReturnCode(wxID_OK);
			this->Show(false);
		}
	}
}
void PersonalRecordDialog::OnReset(wxCommandEvent & event)
{
	Init(); //初始化 介面相關控制元件資料
	TransferDataToWindow();//將資料更新到介面上
}
void PersonalRecordDialog::OnCancel(wxCommandEvent & event)
{
	if(IsModal())
		EndModal(wxID_OK);
	else
	{
		SetReturnCode(wxID_OK);
		this->Show(false);
	}
}
void PersonalRecordDialog::OnHelp(wxCommandEvent & event)
{
    //暫定
}

void PersonalRecordDialog::OnVoteUpdate(wxUpdateUIEvent & event)
{
	wxSpinCtrl *ageCtrl = (wxSpinCtrl *)FindWindow(ID_SAGE);
	if(ageCtrl->GetValue() < 18)//控制年齡小於18時控制元件失效,不檢測
	{
		event.Enable(false);
		event.Check(false);
	}
	else
		event.Enable(true);
}

3、 剩餘成員函式

//初始化資料成員
void PersonalRecordDialog::Init()
{
	SetName(wxT("hh"));
	SetSex(true);
	SetAge(24);
	SetVote(true);
}

//將資料成員更新到對應控制元件上 
//當前沒有註釋的是簡單實現,註釋的是另一種方法(詳細看程式碼的註釋)
bool PersonalRecordDialog::TransferDataToWindow()
{
	wxTextCtrl *nameCtrl = (wxTextCtrl *)FindWindow(ID_NAME);
	wxSpinCtrl *ageCtrl = (wxSpinCtrl *)FindWindow(ID_SAGE);
	wxChoice *sexCtrl = (wxChoice *)FindWindow(ID_SEX);
	wxCheckBox *voteCtrl = (wxCheckBox *)FindWindow(ID_VOTE);
	nameCtrl->SetValue(m_name);
	ageCtrl->SetValue(m_age);
	sexCtrl->SetSelection(m_sex);
	voteCtrl->SetValue(m_vote);
	/*FindWindow(ID_NAME)->SetValidator(
		wxTextValidator(wxFILTER_ALPHA, &m_name));//使用wxTextValidator驗證器使用wxFILTER_ALPHA校驗方法
	//後續可以通過SetIncludes 和 SetExcludes 函式那些字元允許和不允許
	FindWindow(ID_SAGE)->SetValidator(
		wxGenericValidator(&m_age));//使用wxGenericValidator驗證器不對資料驗證,只負責傳輸資料
	FindWindow(ID_SEX)->SetValidator(
		wxGenericValidator(&m_sex));
	FindWindow(ID_VOTE)->SetValidator(
		wxGenericValidator(&m_vote));*/

	return true;
}
//將介面控制元件內容更新到資料成員
bool PersonalRecordDialog::TransferDataFromWindow()
{
	wxTextCtrl *nameCtrl = (wxTextCtrl *)FindWindow(ID_NAME);
	wxSpinCtrl *ageCtrl = (wxSpinCtrl *)FindWindow(ID_SAGE);
	wxChoice *sexCtrl = (wxChoice *)FindWindow(ID_SEX);
	wxCheckBox *voteCtrl = (wxCheckBox *)FindWindow(ID_VOTE);
	m_name = nameCtrl->GetValue();
	m_age = ageCtrl->GetValue();
	m_sex = sexCtrl->GetSelection();
	m_vote = voteCtrl->GetValue();
	return true;
}

//設定控制元件幫助資訊(懸停提示)
void PersonalRecordDialog::SetDialogHelp()
{
	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_SAGE)->SetHelpText(ageHelp);
	FindWindow(ID_SAGE)->SetToolTip(ageHelp);

	FindWindow(ID_SEX)->SetHelpText(sexHelp);
	FindWindow(ID_SEX)->SetToolTip(sexHelp);

	FindWindow(ID_VOTE)->SetHelpText(voteHelp);
	FindWindow(ID_VOTE)->SetToolTip(voteHelp);
}

4、例項化app

class MyApp : public wxApp
{
public:
	virtual bool OnInit();
};

IMPLEMENT_APP(MyApp)//例項化

bool MyApp::OnInit()
{

	PersonalRecordDialog *personal = new PersonalRecordDialog(wxT("Personal Record"));
	personal->ShowModal();//表示模式對話方塊

	return true;
}

快去試試把,歡迎大家留言哈