Получение числового значения из wxTextCtrl - PullRequest
0 голосов
/ 23 февраля 2019

Я изучаю 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 голосов
/ 24 февраля 2019

Вызов TransferDataFromWindow() передает данные, используя валидаторы окна children , а не самого окна.Вы можете вызвать lInTrac->GetValidator()->TransferFromWindow() напрямую, чтобы заставить ваш текущий код работать, но на самом деле сама идея использования явных обработчиков и валидаторов вместе является подозрительной: ваш код будет более понятным, если вы используете один или другой, но не оба этих механизма вместе.

Т.е. либо вам необходимо использовать (возможно, пользовательский) валидатор для комбинированного списка или, возможно, переопределить FMWnd::Transfer{To,From}Window() для обработки этого комбинированного списка и удаленияonTrackerChange() полностью, или , вы просто должны получить значение непосредственно из текстового элемента управления, используя его метод GetValue() в вашем явном обработчике.

Если вы хотите немедленное обновление, последнее являетсяЕдинственный способ сделать это, так как использование валидатора действительно совместимо только с некоторой кнопкой «Применить» / «Отправить».

...