我正在学习wxWidgets,而不是wxPython,是真正的C ++库。
我在用wxTextCtrl
绑定双精度变量时遇到麻烦。据我了解,应该通过wxValidator
模板完成。
这里有一个示例代码,我想将其保留在数组中并编辑5个不同的双打。要从一个值切换到另一个值,我使用wxComboBox
。该代码的主要问题是,在调用tracable
时,它不会更新双变量TransferDataFromWindow()
,并且在调用TransferDataToWindow()
函数时,也不会从该变量中读取值。
#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&xit\tAlt-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 Windows\n");
// lInTrac->TransferDataToWindow();
}
void FMWnd::OnQuit(wxCommandEvent&)
{
Close(true);
}
void FMWnd::OnAbout(wxCommandEvent&)
{
wxMessageBox(wxT("wxConfig demo\n(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:%g\n",curTrackers,allTrac[curTrackers],tracable);
}
if (event.GetSelection() == 0){
tracable = 0.;
curTrackers = -1;
lInTrac->SetValue("0.0");
printf("Reset Tracker\n");
} else {
curTrackers = event.GetSelection() - 1;
tracable = allTrac[curTrackers];
TransferDataToWindow();
lInTrac->TransferDataToWindow();
printf("Set Tracker to %d\n",curTrackers);
}
}
答案 0 :(得分:1)
调用TransferDataFromWindow()
会使用窗口 children 的验证器而不是窗口本身来传输数据。您可以直接调用lInTrac->GetValidator()->TransferFromWindow()
来使当前代码正常工作,但实际上,同时使用显式处理程序和验证程序的整个想法是可疑的:如果使用一个或另一种,但不是所有这两种机制都结合在一起。
即 您需要为组合框使用(可能是自定义的)验证器,或者覆盖FMWnd::Transfer{To,From}Window()
来处理此组合框并完全删除onTrackerChange()
,或者是 em>您应该只在显式处理程序中使用文本控件的GetValue()
方法直接从文本控件获取值。
如果要立即更新,则后者是唯一的方法,因为使用验证器实际上仅与某种“应用” /“提交”按钮兼容。