我正在学习wxwidgets,而不是wxpython,实际的C 库。我遇到了与wxTextCtrl
绑定双变量的麻烦。据我所知,应该通过wxValidator
模板完成。
在这里,我想将其保留在数组中并编辑5个不同的双打。要从值转换为值,我使用wxComboBox
。主要问题该代码在调用 TransferDataFromWindow()
时不会更新double tracable
,并且在调用 TransferDataToWindow()
functions时不会从该变量读取值。
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif //precompiled headers
#include "wx/log.h"
#include "wx/config.h"
#include "wx/splitter.h"
#include "wx/sizer.h"
#include <wx/spinctrl.h>
#include <wx/grid.h>
//#ifndef wxHAS_IMAGES_IN_RESOURCES
//#include "../sample.xpm"
//#endif
class FMApp: public wxApp
{
public:
virtual bool OnInit();
virtual int OnExit();
};
IMPLEMENT_APP(FMApp)
class FMWnd: public wxFrame
{
public:
FMWnd();
virtual ~FMWnd();
// callbacks
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnSelectDB(wxCommandEvent& event);
private:
uint nTrackers;
double tracable;
double *allTrac;
int curTrackers;
//=== LIFE ===//
wxTextCtrl *lInTrac;
wxComboBox *lTrac;
/*inner functions*/
void onTrackerChange( wxCommandEvent &);
wxDECLARE_EVENT_TABLE();
};
enum{
ID_TRACK= wxID_HIGHEST,
ID_UNIT,
//------- EVENTS -------//
SELECT_TRANS,
ID_ADD_TRACKABLE,
FM_LAST
};
bool FMApp::OnInit()
{
if ( !wxApp::OnInit() ) return false;
SetVendorName(wxT("TEST"));
SetAppName(wxT("---"));
FMWnd *frame = new FMWnd;
frame->Show(true);
return true;
}
int FMApp::OnExit()
{
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wx/datetime.h"
#include "wx/colour.h"
#include "wx/notebook.h"
#include "wx/valgen.h"
#include "wx/valnum.h"
wxBEGIN_EVENT_TABLE(FMWnd, wxFrame)
EVT_MENU(wxID_EXIT, FMWnd::OnQuit)
EVT_MENU(wxID_ABOUT, FMWnd::OnAbout)
EVT_COMBOBOX(ID_TRACK, FMWnd::onTrackerChange)
wxEND_EVENT_TABLE()
FMWnd::FMWnd()
: wxFrame((wxFrame *) NULL, wxID_ANY, wxT("- TEST -"),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE|wxWS_EX_VALIDATE_RECURSIVELY
)
{
// menu
wxMenu *file_menu = new wxMenu;
file_menu->AppendSeparator();
file_menu->Append(wxID_EXIT, wxT("E&xittAlt-X"), wxT("Exit the program"));
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, wxT("&File"));
SetMenuBar(menu_bar);
// child controls
wxPanel* p = new wxPanel(this, wxID_ANY);
wxBoxSizer *lAmExDlg = new wxBoxSizer( wxHORIZONTAL );
lAmExDlg->Add(lTrac = new wxComboBox(p,ID_TRACK),0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL| wxFIXED_MINSIZE, 3);
lTrac->Append(wxT("---"));
lTrac->Append(wxT("-1-"));
lTrac->Append(wxT("-2-"));
lTrac->Append(wxT("-3-"));
lTrac->Append(wxT("-4-"));
lTrac->Append(wxT("-5-"));
lTrac->SetSelection(0l);
lTrac->SetEditable(false);
lAmExDlg->Add(lInTrac = new wxTextCtrl(p,wxID_ANY, wxT(""),wxDefaultPosition,wxDefaultSize,wxTE_LEFT,
wxMakeFloatingPointValidator(3,&tracable,wxNUM_VAL_THOUSANDS_SEPARATOR |wxNUM_VAL_NO_TRAILING_ZEROES)),
4, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 3);
wxBoxSizer *lTopSizer = new wxBoxSizer( wxVERTICAL );
lTopSizer->Add(lAmExDlg, 1, wxEXPAND );
p->SetSizer(lTopSizer);
wxBoxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
topSizer->SetMinSize(250, 100);
topSizer->Add(p, 1, wxEXPAND);
SetSizerAndFit(topSizer);
curTrackers = -1;
tracable = 20.0;
nTrackers = 5;
allTrac = new double[nTrackers];
for(int cnt=0; cnt<nTrackers; ++cnt)allTrac[cnt] = 0.0;
if (TransferDataToWindow())fprintf(stderr,"Cannot Transefer Data to Windowsn");
// lInTrac->TransferDataToWindow();
}
void FMWnd::OnQuit(wxCommandEvent&)
{
Close(true);
}
void FMWnd::OnAbout(wxCommandEvent&)
{
wxMessageBox(wxT("wxConfig demon(c) 1998-2001 Vadim Zeitlin"), wxT("About"),
wxICON_INFORMATION | wxOK);
}
FMWnd::~FMWnd()
{
delete[] allTrac;
}
void FMWnd::onTrackerChange(wxCommandEvent& event){
TransferDataFromWindow();
lInTrac->TransferDataFromWindow();
if(curTrackers >= 0){
allTrac[curTrackers]=tracable;
printf("Tr:%d Var:%g Val:%gn",curTrackers,allTrac[curTrackers],tracable);
}
if (event.GetSelection() == 0){
tracable = 0.;
curTrackers = -1;
lInTrac->SetValue("0.0");
printf("Reset Trackern");
} else {
curTrackers = event.GetSelection() - 1;
tracable = allTrac[curTrackers];
TransferDataToWindow();
lInTrac->TransferDataToWindow();
printf("Set Tracker to %dn",curTrackers);
}
}
使用窗口儿童的验证器调用TransferDataFromWindow()
,而不是窗口本身。您可以直接调用lInTrac->GetValidator()->TransferFromWindow()
以使您的当前代码正常工作,但实际上,将显式处理程序和验证器一起使用的整个想法是可疑的:如果您使用一个或另一个,您的代码将更加清楚但并非这两个机制在一起。
即。您需要使用(可能是自定义的)验证器作为Combobox,或者也许覆盖FMWnd::Transfer{To,From}Window()
来处理此组合,并完全删除onTrackerChange()
,或或您应该只能获得值直接使用其显式处理程序中的GetValue()
方法从文本控件中。
如果您想立即更新,后者是这样做的唯一方法,因为使用验证器实际上仅与某种"应用"/"提交"按钮兼容。