From: Everett, T. <TEverett@ALASCOM.ATT.com> - 2002-09-06 19:16:24
|
-----Original Message----- From: Mattia Barbon [mailto:mb...@ds...] Sent: Friday, September 06, 2002 8:38 AM To: Everett, Toby Cc: wxp...@li... Subject: Re: [wxperl-users] Wx::ComboBox::SetValue ineffective when wxCB_READONLY is set > If this is under wxMSW, it is a known bug; I can reproduce it > with CVS wxWindows 2.3.3 under Windows; wxGTK (and I assume wxMOTIF), > seem to work fine. I am going to commit a fix for this in wxWindows; > this should be in 2.3.3 release. MSW = Microsoft Windows, right? BTW, where is the best place to search for known bugs? > > insufficiently grateful, wxPerl does really rock! I'm still stumbling my > Well, if reporting bugs (with testcases) > is being ungrateful, I want more ungrateful people ;-) It's a deal:) > > way through the darkness, but I'm making reasonably good progress in doing > > my first test port of a Tk app. There are definitely some Tk things I miss > > (-textvariable, for one:), but I will say the native look and feel is > ^^^^^^^^^^^^^ > Curious: what does it do? It hooks a variable to the value of a widget. You pass it a reference to a scalar, like so: <create_new_widget> . . . -textvariable => \$myvar . . . Then, whenever you update $myvar, the value in the equivalent of a TextCtrl or whatever changes. Similarly, when you change the value in the widget interactively, the value in $myvar changes. I'm not quite sure how it's done internally. A widget->variable equivalent can be done like so: EVT_TEXT($self, $_, sub { my($self, $event) = @_; $myvar = $widget->GetValue(); }); Here's another approach. This relies upon Stephen Lidie's Tie::Watch. ===== Wx/TiedVariable.pm BEGIN ===== package Wx::TiedVariable; use Tie::Watch; sub Set { my($self, $ref) = @_; ref($ref) eq 'SCALAR' or die "Usage: Wx::TiedVariable::Set(\$widget, \\\$scalar)."; $self->SetValue($$ref); my $watch = $self->{"\0TIEWATCH"} = Tie::Watch->new( -variable => $ref, -fetch => sub {$self->GetValue()}, -store => sub {$self->SetValue($_[1])}, ); } 1; ====== Wx/TiedVariable.pm END ====== ===== demo.pl BEGIN ===== use strict; package MyFrame; use Wx qw(:everything); use Wx::Event qw(EVT_BUTTON); use Wx::TiedVariable; use vars qw(@ISA); @ISA=qw(Wx::Frame); sub new { my $class = shift; my $self = $class->SUPER::new(undef, -1, $0, [-1,-1], [-1,-1]); my $wx = $self->{wx} = {}; $wx->{pnl} = Wx::Panel->new($self, -1); $wx->{szr} = $_ = Wx::BoxSizer->new(wxVERTICAL); $wx->{pnl}->SetSizer($_); $wx->{pnl}->SetAutoLayout(1); my $value = "foobar"; $wx->{txtDemo} = $_ = Wx::TextCtrl->new($wx->{pnl}, -1, '', [-1,-1], [-1,-1]); $wx->{szr}->Add($_, 0, wxALIGN_LEFT|wxALL, 5); Wx::TiedVariable::Set($_, \$value); $wx->{butEdit} = $_ = Wx::Button->new($wx->{pnl}, -1, "Edit"); $wx->{szr}->Add($_, 0, wxALIGN_CENTRE|wxALL, 5); EVT_BUTTON($self, $_, sub { my($self, $event) = @_; $value = Wx::GetTextFromUser("Edit the value of \$value:", 'Value', $value, $self); }); $wx->{szr}->Fit($self); return $self; } package MyApp; use Wx; use vars qw(@ISA); @ISA=qw(Wx::App); sub OnInit { my $self = shift; my $frame = MyFrame->new(); $self->SetTopWindow($frame); $frame->Show(1); } package main; (my $app = MyApp->new())->MainLoop(); ====== demo.pl END ====== Note that the calling syntax is Wx::TiedVariable::Set($widget, $$ref). This is intentional, because it would allow Set to be hooked into the Wx:: hierarchy at the right point using something akin to *Wx::RightHierarchyPoint::SetTiedVariable = \&Wx::TiedVariable::Set; Then you could just use $widget->SetTiedVariable(\$value); I just didn't know at what point in the hierarchy GetValue and SetValue became active. --Toby Everett |