=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
>
>
>
>

Reply via email to