=begin comment Dear Mark Thank you for your prompt reply. This program I'm running is not small (~580 lines), and I didn't want to clog the forum. I any case, I went through the program now, and sifted out the irrelevant parts ( irrelevant for this question) (even so it's ~140 lines). Here it is - it's runnable.
Please note the following: the program contains 4 packages, the relevant ones are "TC_test" and "MyValidator". The program logic (trivially simple) goes like this: package "main" calls package "MyForm", which displays a frame. Clicking the button "select_btn" calls sub "prep_query", which calls package "TC_test". package "TC_test" creates a text control called "$TCtrl", to which "TCtrl_v": a "MyValidator" validator is attached. Like I said in the OP, before leaving sub "new TC_test" it tries to executes: $TCtrl_v->TransferToWindow; and breaks saying: "Can't call method "SetValue" on an undefined value at ... .pl line 150." Many TIA Helen =end comment =cut use strict; use warnings; use Wx; package MyForm; # ------------------------------------- package MyForm:: use strict; use warnings; use 5.014; use parent -norequire, 'Wx::Frame'; use Wx::Event qw(EVT_BUTTON); use Wx qw[:everything]; sub new { #1 --------------------------- new MyForm:: my $class = shift; my $self = $class->SUPER::new( undef, -1, 'Frame class: MyForm', wxDefaultPosition, wxDefaultSize ); my $panel = Wx::Panel->new( $self, -1, wxDefaultPosition, wxDefaultSize); # ... my $select_btn = Wx::Button->new( $panel, -1, 'DB Select query', wxDefaultPosition, wxDefaultSize); EVT_BUTTON( $self, $select_btn, sub { #3 prep_query(); } #3 end sub ); # end EVT_BUTTON continue_btn call # ... my $sizer = Wx::BoxSizer->new(wxVERTICAL); my $sizer1_h = Wx::BoxSizer->new(wxHORIZONTAL); $sizer1_h -> Add ( $select_btn, 0, wxALL, 5 ); # ... $sizer->Add( $sizer1_h, 1, wxEXPAND); $panel->SetSizer($sizer); $panel->Fit; return $self; sub prep_query { #2 preparing query my $select_query_frame = TC_test->new; $select_query_frame->Show(1); } #2 end sub prep_query } #1 end sub new MyForm:: # ... 1; # end package MyForm package TC_test; # ----------------------------------- package TC_test:: use strict; use warnings; use Wx; use 5.014; use parent -norequire, 'Wx::Frame'; use Wx::Event qw(EVT_BUTTON EVT_CLOSE); use Wx qw( wxDefaultPosition wxDefaultSize wxTE_PROCESS_ENTER); # ... sub new { # -------------------------------------- new TC_test:: my $class = shift; # ... my $self = $class->SUPER::new( undef, -1, 'Frame class: TC_test', wxDefaultPosition, wxDefaultSize); my $panel2 = Wx::Panel->new( $self, -1, wxDefaultPosition, wxDefaultSize); # ... my $TCtrl = Wx::TextCtrl->new($panel2, -1, q{}, wxDefaultPosition, [20,-1], wxTE_PROCESS_ENTER); my $TCtrl_v = MyValidator->new( \$main::text_value); $TCtrl->SetValidator( $TCtrl_v); my $sizer_main = Wx::FlexGridSizer->new(7,7,5,5); # ... $sizer_main->Add($TCtrl, 0); # ... $sizer_main->Fit($self); $sizer_main->SetSizeHints($self); # ... EVT_CLOSE( $self, sub { #2 if( not $TCtrl_v->Validate ) { Wx::LogMessage( "Data is invalid" ); return; } if( not $TCtrl_v->TransferFromWindow ) { Wx::LogMessage( "Error in data transfer" ); return; } $self->Wx::Window::Destroy; } #2 end sub of EVT_CLOSE ); #1 end EVT_CLOSE call $TCtrl_v->TransferToWindow; # here it breaks saying: "Can't call method "SetValue" on an undefined value at ... etc...". return $self; } #1 end sub new TC_test:: 1; # end package TC_test #------------------- end package TC_test package MyValidator; #----------------- package MyValidator # helped by: http://articles.mongueurs.net/magazines/linuxmag71.html use strict; use Wx qw(wxOK wxICON_ERROR); use parent -norequire, 'Wx::PlValidator'; # Classe de base sub new { # Constructeur my $class = shift; my $var_r = shift; # Ref de la variable associe my $this = $class->SUPER::new; $this->{var_r} = $var_r; # Pour consultation ultrieure return $this; } # end sub new sub Clone { # Indispensable pour les Validators car ils sont clon?s en interne my $this = shift; my $new = MyValidator->new( # Transmet la reference a la variable associe $this->{var_r} ); return $new; } # end sub Clone sub Validate { # Appel?e par Wx::Dialog->Validate my( $this, $dialog ) = @_; my $V_var = $this->GetWindow->GetValue; # La methode GetWindow retourne le widget concerne # Verification personnalisee if ($V_var !~ /^[A-Z ]+$/) { # ici uniquement des caracteres alphabetiques majuscules et l'espace Wx::MessageBox( "Erreur: $V_var n'est pas une valeur admissible.", # Affichage d'un Pop-up informatif "Error", wxOK|wxICON_ERROR, undef ); return 0; # Signale notre probleme au Dialog } 1; # Signale que tout va bien } # end sub Validate sub TransferFromWindow { # Copie le contenu du controle dans la variable associe my $this = shift; ${$this->{var_r}} = $this->GetWindow->GetValue; 1; # Signale que tout va bien } # end sub TransferFromWindow sub TransferToWindow { # Copie le contenu de la variable associ?e dans le controle my $this = shift; $this->GetWindow->SetValue( ${$this->{var_r}} ); 1; # Signale que tout va bien } # end sub TransferToWindow 1; # end package MyValidator; #------- end package MyValidator package main; # ---------------------------------------------- package main:: use strict; use warnings; # ... # déclaration et initialisation de la variable interne associée au Validator $main::text_value = 'FOO BAR'; my $app = Wx::SimpleApp->new; my $frame = MyForm->new; $frame->Show(1); $app->MainLoop; 1; On Sun, Jun 16, 2013 at 4:48 AM, Mark Dootson <mark.doot...@znix.com> wrote: > Hi, > > > On 15/06/2013 22:23, Helen Craigman wrote: > >> Dear esteemed WxPerl experts and users: >> I have been trying to incorprate a validator on a TextCtrl widget, using >> PlValidator (following this: >> > ...... > > This gives the error: "Can't call method "SetValue" on an undefined >> value at..." etc. >> > > As far as my own usage is concerned, classes derived from Wx::PlValidator > work perfectly. > > For me to either help you to get your Wx::PlValidator derived class > working, or identify some bug in Wx::PlValidator, you would have to post > some code that can be run and demonstrates the failure you are experiencing. > > The code snippet you have posted doesn't show a validator being assigned > to a Wx::TextCtrl - so it cannot be an accurate representation of the code > that fails for you. You clearly have worked out how a Validator should work > if you get as far as the error reported, and you probably just need a > simple adjustment in your code to make it work. But without seeing the > actual failing code I have no clue what might be causing the failure. > > I feel that I am always giving negative answers to the Wx questions you > ask on this list and Perl Mongers - and I feel really bad about this as you > have clearly figured out 99% of what is required yourself. > > I can't help if you don't post some actual code - or even a snippet taken > from actual code. I'd guess you are missing a Clone method in your derived > class, but who knows. The code you posted can't be the code you are running. > > Regards > > Mark > > > >