从wxTextCtrl

时间:2019-02-22 23:46:16

标签: c++ wxwidgets wxtextctrl

我正在学习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);
    }

}

1 个答案:

答案 0 :(得分:1)

调用TransferDataFromWindow()会使用窗口 children 的验证器而不是窗口本身来传输数据。您可以直接调用lInTrac->GetValidator()->TransferFromWindow()来使当前代码正常工作,但实际上,同时使用显式处理程序和验证程序的整个想法是可疑的:如果使用一个或另一种,但不是所有这两种机制都结合在一起。

您需要为组合框使用(可能是自定义的)验证器,或者覆盖FMWnd::Transfer{To,From}Window()来处理此组合框并完全删除onTrackerChange(),或者是 em>您应该只在显式处理程序中使用文本控件的GetValue()方法直接从文本控件获取值。

如果要立即更新,则后者是唯一的方法,因为使用验证器实际上仅与某种“应用” /“提交”按钮兼容。