Home > Archive > PerlTk > March 2005 > How to make Megawidget with ONE Entry and TWO Variables
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
How to make Megawidget with ONE Entry and TWO Variables
|
|
|
| Hi Folks
another question to designing a mega-widget.
I would like to create a mega-widget that contains one simple entry's and
two text-variables.
the mega-widget should be created as follows:
my $megawidget->MegaWidet(-invar => \$invar,
-outvar => \$outvar);
the user should enters a value into $invar and the widget is to give back
$invar and dependant on $invar another value in $outvar.
How to process this into the mega-widget ?
Has somebody any examples or other ways in order to check this ?
Thanks
Pit
| |
| Rob Seegel 2005-03-14, 8:57 am |
| I'm sorry - I'm afraid I don't think I understand the question.
So, $invar would be used to populate the entry, correct? Are you saying
that whenever $invar changed, there would be some sort of internal test
that set $outvar depending on what the value of $invar was?
What sort of Megawidget are you trying to create?
Rob
Pit wrote:
> Hi Folks
>
> another question to designing a mega-widget.
>
> I would like to create a mega-widget that contains one simple entry's and
> two text-variables.
>
> the mega-widget should be created as follows:
>
> my $megawidget->MegaWidet(-invar => \$invar,
> -outvar => \$outvar);
>
> the user should enters a value into $invar and the widget is to give back
> $invar and dependant on $invar another value in $outvar.
>
> How to process this into the mega-widget ?
>
> Has somebody any examples or other ways in order to check this ?
>
> Thanks
> Pit
>
>
>
| |
|
| the megawidget is to do following:
user enters a value in the entry. the entered value should be contained in
$invar (i.e. a customer number).
in the megawidget with $invar will be reading in a database and a variable
$outvar should be filled with a value (i.e the customer name). this value
also should be available in the perl-script.
Pit
| |
| Reinhard Pagitsch 2005-03-14, 3:59 pm |
| Hello Pit,
Pit wrote:
> the megawidget is to do following:
>
> user enters a value in the entry. the entered value should be contained in
> $invar (i.e. a customer number).
> in the megawidget with $invar will be reading in a database and a variable
> $outvar should be filled with a value (i.e the customer name). this value
> also should be available in the perl-script.
>
> Pit
I think a sample code snippet would be helpfull.
If I want to store values for further use I use a sub and a global
variable to get the data and store them for further use. But I have only
Perl 5.6.1 :(
regards,
Reinhard
| |
|
| here the little code snippet ...
package Tk::MyMega;
use base qw/Tk::Frame/;
use strict;
Construct Tk::Widget 'MyMega';
sub Populate {
my($self, $args) = @_;
$self->SUPER::Populate($args);
$self->{entry} = $self->Entry->pack;
$self->ConfigSpecs(
-outvar => '-textvariable',
-intvar => 'here I need some help',
);
} # end Populate
# $outvar contains the users input
# $intvar is to set inside $MyMega and should be available in package
main
package main;
use Tk;
#use Tk::MyMega;
use strict;
my $mw = MainWindow->new;
my $outvar = "";
my $intvar = "";
my $mm = $mw->MyMega(
-outvar => \$outvar,
-intvar => \$intvar,
)->pack;
MainLoop;
Pit
| |
| Rob Seegel 2005-03-14, 3:59 pm |
| Pit wrote:
> the megawidget is to do following:
>
> user enters a value in the entry. the entered value should be contained in
> $invar (i.e. a customer number).
> in the megawidget with $invar will be reading in a database and a variable
> $outvar should be filled with a value (i.e the customer name). this value
> also should be available in the perl-script.
>
Huh. I feel like I'm still missing something. I'm still not really
seeing what you intend to use this for. Oh well, I'll take a stab at it
anyway.
From your description it seems like you want a simple Entry that
displays one value after being passed another. I think if it were me, I
would probably be adding a method to this sort of thing, and I might
leave one textvariable in place for accessing the result once changed. I
even wonder if this needs to be a megawidget.
At any rate, I often find it helpful unless I absolutely understand what
it is I'm trying to do, to implement something with a simple script
before I try to make it a megawidget.
Is this something like what you are looking to do?
use Tk;
my %customerMap = (
1 => "Bob",
2 => "Joe",
12 => "Billy",
20 => "Ann",
22 => "Sally",
30 => "Stig"
);
my $mw = MainWindow->new;
## Setup ID
my $id;
my $idLabel = $mw->Label(-text => 'Id: ');
my $idEntry = $mw->Entry(-textvariable => \$id);
$idLabel->grid($idEntry);
$idEntry->bind('<KeyPress>', \&findCustomerById);
## Setup Name
my $name;
my $nameLabel = $mw->Label(-text => 'Name: ');
my $nameEntry = $mw->Entry(-textvariable => \$name);
$nameLabel->grid($nameEntry);
MainLoop;
sub findCustomerById
{
$name = $customerMap{$id} || "";
}
__END__
Note that the subroutine "findCustomerById" could also have been
implemented like this, if I didn't want to use textvariables.
sub findCustomerById
{
my $entry = shift;
my $key = $entry->get;
my $name = $customerMap{$key} || "";
$nameEntry->delete(0, 'end');
$nameEntry->insert(0, $name);
}
| |
|
| my intention is to create a megawidget for entering a customer number. Into
the megawidget takes place a database select to check the entered number
and find the right set in the customer table.
In case of success the megawidget should return the customer-name.
in the calling script I only want to do following
my $cust_entry = MyMegaCustomer
(-number => \$number,
-name => \$name
)->pack();
$number is the entered customer number
$name is the returned customer name
Pit
| |
| Rob Seegel 2005-03-14, 3:59 pm |
| Pit wrote:
> my intention is to create a megawidget for entering a customer number. Into
> the megawidget takes place a database select to check the entered number
> and find the right set in the customer table.
> In case of success the megawidget should return the customer-name.
>
> in the calling script I only want to do following
>
> my $cust_entry = MyMegaCustomer
> (-number => \$number,
> -name => \$name
> )->pack();
>
> $number is the entered customer number
> $name is the returned customer name
>
Ok. I think I've got it -- I can be a bit slow when I'm feeling under
the weather, and I've got a doozy of a cold. Well, I probably wouldn't
use a textvariable for -number, then. I would probably do something like
this (It's an variation of previous example code).
I'd also like to suggest that you consider encapsulating your data
access logic into another class to keep the DBI code (or whatever it is
you're using out of the Tk code) Let's say you call your class
CustomerDao (Customer Data Access Object).
package Tk::MyMega;
use base qw/Tk::Frame/;
use carp;
use strict;
Construct Tk::Widget 'MyMega';
sub Populate
{
my($self, $args) = @_;
$self->{DAO} = delete($args->{'-customerDao'}) ||
croak "CustomerDao was not defined!";
$self->SUPER::Populate($args);
my $e = $self->Component(Entry => 'entry')->pack;
$self->ConfigSpecs(
-outvar => [{-textvariable => $e}, qw/outVar OutVar/],
-invar => [qw/METHOD inVar InVar/]
);
}
sub invar
{
my ($self, $value) = @_;
return $self->{Configure}{-invar} unless defined $value;
my $dao = $self->{DAO};
my $entry = $self->Subwidget('entry');
my $name = $dao->findCustomerNameById($value);
$entry->delete(0, 'end');
$entry->insert(0, $name);
}
| |
| Rob Seegel 2005-03-14, 3:59 pm |
| Rob Seegel wrote:
> $self->{DAO} = delete($args->{'-customerDao'}) ||
> croak "CustomerDao was not defined!";
It might not be a bad idea to do some simple type checking here.
my $dao = delete($args->{'-customerDao'});
croak "Invalid value for -customerDao option"
if (!defined($dao) || ref($dao) ne 'CustomerDao');
or maybe something a bit more flexible:
croak "-customerDao undefined\n" unless defined $dao;
croak "-customerDao object does not support findCustomerNameById method"
if (!$dao->can("findCustomerNameById"));
Just a few thoughts...
Rob
| |
|
| Many thanks, but this is not exactly what I want.
In your example the entered customer number will be overwritten with the
name.
This is not to happen. The entered number should be visible in the
entry-widget, the name only will be returned. In most cases the name will
be shown in another widget or maybe invisible
Pit
| |
| Rob Seegel 2005-03-15, 8:57 am |
| Pit wrote:
> Many thanks, but this is not exactly what I want.
>
> In your example the entered customer number will be overwritten with the
> name.
> This is not to happen. The entered number should be visible in the
> entry-widget, the name only will be returned. In most cases the name will
> be shown in another widget or maybe invisible
>
Yes, I misunderstood (again). I thought that the customer number would
be supplied via the textvariable and NOT via the Entry widget. It wasn't
a case of overwritting it. The customer number was never being set to
begin with. I'm starting to think that Steve was on the right track in
the very beginning with his approach.
Normally, a user would be expected to interact with the GUI, right? A
user would add the customer number directly into the Entry widget. If
so, what would you expect to trigger the datbase operation? I mean, you
probably wouldn't want the operation to happen each time someone entered
a keystroke. Would there be a button, or would you bind to <Return>?
Rob
| |
|
| the database action starts when user presses Return or Tab
Pit
| |
| Rob Seegel 2005-03-16, 3:58 am |
| In-Reply-To: < 1cf4ea9649e5cbb8f733818abb542921@localho
st.talkaboutprogramming.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Message-ID: <srmdnQoiYLs_AKrfRVn-tA@comcast.com>
Lines: 57
NNTP-Posting-Host: 69.250.244.6
X-Trace: sv3-ArT/ 4HQVPcMLdlaqg3gDwWbkasSUNPq21qXBfaz8437S
kk0oIeENvndkB/ p6RzzPOFfAXGfpj1I8gNp!7yRp+qP88NilMCjO1h
NfVVAiYF5eBBcDbd2xYKg/PXT6tKFCnfuzUuW2BZgP
X-Complaints-To: abuse@comcast.net
X-DMCA-Complaints-To: dmca@comcast.net
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.31
Xref: number1.nntp.dca.giganews.com comp.lang.perl.tk:43468
Pit wrote:
> the database action starts when user presses Return or Tab
>
> Pit
>
This should be enough to get you going with it... There's plenty of
other ways this could be done. Since it only uses one Entry widget, an
alternative would have been to derive it from an Entry widget and not a
Frame. In terms of total code, it probably wouldn't have saved you too
much, but it might have been a little simpler.
package Tk::MyMega;
use base qw/Tk::Frame/;
use carp;
use strict;
Construct Tk::Widget 'MyMega';
sub Populate
{
my($self, $args) = @_;
$self->{DAO} = delete($args->{'-customerDao'}) ||
croak "CustomerDao was not defined!";
$self->SUPER::Populate($args);
my $e = $self->Component(Entry => 'entry')->pack;
$e->bind('<Return>', [$self => 'LookupName']);
$e->bind('<FocusOut>', [$self => 'LookupName']);
$self->ConfigSpecs(
-invar => [{-textvariable => $e}, qw/inVar InVar/],
-outvar => [qw/PASSIVE/]
);
}
## Another suggestion - you might consider modifying this method
## to store a copy of id each time a db lookup is done, and only
## do a lookup if the id is different. This saves you a few
## unneeded trips to the DB.
sub LookupName
{
my $self = shift;
my $id = $self->Subwidget('entry')->get;
my $nameSR = $self->cget('-outvar');
$$nameSR = $self->{DAO}->findCustomerNameById($id)
if defined $nameSR;
}
__END__
|
|
|
|
|