Help needed with using validator please Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Help needed with using validator please

Post by Antipole »

I cannot get a standard validator to get access to entered data.

The following is a cut-down version of my code:

Code: Select all

#include <wx/wx.h>
#include <wx/dialog.h>
#include <wx/button.h>
#include "wx/textctrl.h"
#include "duktape.h"

wxString textField;

void onDialogOK(wxCommandEvent & event){
    wxString theData;
    
    theData = textField;
    // pause here to view theData
    }

duk_ret_t duk_dialog(duk_context *ctx) {  // provides wxWidgets dialogue
    int button_ID;
    wxTextCtrl* textCtrl;
    wxBoxSizer* buttonBox;
    wxButton* button;
        
    // create the dialog
    button_ID = 1000;
    wxDialog *dialog = new wxDialog(NULL,  wxID_ANY, wxT("JavaScript dialogue"), wxDefaultPosition, wxDefaultSize);
    wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);  // A top-level sizer
    buttonBox = new wxBoxSizer(wxHORIZONTAL);
    dialog->SetSizer(topSizer);
    textField = wxT("(Default text)");
    textCtrl = new wxTextCtrl ( dialog, i, wxT(""), wxDefaultPosition, wxDefaultSize, 0 ,
			wxTextValidator(wxFILTER_NONE, &textField));
    boxSizer->Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
    button = new wxButton ( dialog, button_ID, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
    buttonBox->Add(button, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    dialog->Bind(wxEVT_BUTTON, &onDialogOK, wxID_ANY);
    // 	also tried button->Bind(wxEVT_BUTTON, &onDialogOK, wxID_ANY);
    dialog->Show(true);
    return 1;
    } 
When I call duk_dialog the dialog displays as expected and the wxTextCtrl field correctly displays the default text "(Default text)", which I have stored in textField. The validator is working to the extent that if I use a filter like wxFILTER_ALPHANUMERIC, it will not let me enter anything other than alphanumerics - no spaces etc. I change the field to something else - like "ChangedText"

When I click on the OK button, the handler onDialogOK is entered. I am testing under Xcode and have a breakpoint set on the // pause here line. theData is still set to the original default text.
It seems the changed data is not being transferred back to textField. Maybe the transferDataFromWindow function is not being called?

Any help on what else I need to do will be really appreciated.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Help needed with using validator please

Post by doublemax »

First of all: In 99% of cases a wxDialog should be used as a modal dialog, called with ShowModal() instead of Show(). Are you sure you want a non-modal one?

You need to call Validate() yourself:
https://docs.wxwidgets.org/trunk/overvi ... or_dialogs

Also, if you just want a dialog to ask the user for a single value, there are ready-to-go dialogs available, e.g.:
https://docs.wxwidgets.org/trunk/classw ... ialog.html
Use the source, Luke!
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Help needed with using validator please

Post by Antipole »

@doublemax...thank you for your help.

(1) This is a JavaScript plugin for OpenCPN - a marine navigation program. I cannot use ShowModal() because that stops all other processing until the user completes the dialogue. I need to yield until OK (I have not got that far yet) or adopt my approach whereby there is a callback to a JavaScript function when the dialogue is completed.

(2) I had seen the page you referred me to but had misunderstood that the default handler would do the validation and transfer. I have now called it myself and it works.

Thank you very much for helping me over this hurdle.

For your information, the cutdown handler now looks like this:

Code: Select all

wxString textField;

void onDialogOK(wxCommandEvent & event){
	wxWindow *window;
    wxButton *button;
    wxString theData;
    
    button = wxDynamicCast(event.GetEventObject(), wxButton);
    window = button->GetParent();
    if ( window->Validate() && window->TransferDataFromWindow() ){
	    theData = textField;
	    // pause here to view theData
        window->Show(false);
   		 } 
    }
 
Post Reply