For Programmers: Free Programming Magazines  


Home > Archive > PerlTk > May 2005 > Newbie question on widget selecting.









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 Newbie question on widget selecting.
Terkel

2005-05-01, 9:03 pm

The purpose of this question is learning rather than trying to actually
build real code.

Up to now I have been making similar widgets with different variables,
like $entrybox1, $entrybox2, etc. Works great because I know exactly
which one I am referring to.

But...

The following code makes a row of entry boxes.

for (my $i = 0; $i<12; $i++) {
$entrybox = $mw->Entry(-width => 8, -textvariable =>
\$entryarray[$i])->place(-x=>10 + ($i*70), -y=>25);
}

The only difference in any of the widgets is that the -textvariable is a
different element in an array. No problem there, that works fine.

What I don't understand is that it looks like I have built 12 identical
boxes with the widget name of "$entrybox". How does TK know which one I
am referring to?

For that matter, how would you click on an entrybox like the above, make
an entry, and be able to tell some subroutine that the text has changed
and which box was changed?

Ok, so I am . (But, having a blast!) Just wish there were more
books on TK, or that the Mastering Perl/TK book was larger:)

Terkel
Rob Seegel

2005-05-01, 9:03 pm

Terkel wrote:

> Up to now I have been making similar widgets with different variables,
> like $entrybox1, $entrybox2, etc. Works great because I know exactly
> which one I am referring to.
>
> But...
>
> The following code makes a row of entry boxes.
>
> for (my $i = 0; $i<12; $i++) {
> $entrybox = $mw->Entry(-width => 8, -textvariable =>
> \$entryarray[$i])->place(-x=>10 + ($i*70), -y=>25);
> }
>
> What I don't understand is that it looks like I have built 12 identical
> boxes with the widget name of "$entrybox". How does TK know which one I
> am referring to?


Well, in the case you presented $entrybox refers to one Entry widget --
the last one you created within your loop. Each time through your loop,
you are reassiging the value of $entrybox to the latest Entry widget
you've created (replacing one Tk::Entry blessed hashref for another).

As you replace each one, you might wonder where they go. After all, the
Entry widgets are still there, even though you now only have direct
access to the first one. Tk maintains an internal tree of all widgets
per MainWindow (I believe), even if you choose not to maintain variables
pointing to each one yourself. After all there's nothing stopping you
from creating an app with a scant number of variables other than the
fact that it can make the code more difficult to write and for others to
read.

When programming with Tcl/Tk you often work with this tree in very
direct ways and in Perl/Tk it is encapsulated behind the OO wrapping.
Each widget is assigned a unique name - usually, it's a lowercase
version of the name with a one-up number appended to it per node. You
don't see it, but your list of Entries are probably named something like:

entry
entry1
entry2
....
entry11

This will vary depending on the number of Entry widgets you created
before your loop. You can optionally assign your own names to each
widget if you want by using the Name option that can only be set at
creation time. (Personally, I've never taken advantage of this feature,
and am content to let Tk to the naming, though it might be handy if you
had to walk though a lot of widgets and wished to find a specific one.
Typically, it's much easier to assign the widget in question to a
variable if it is that important.)

Running something like the following will give you a basic idea
espectially if you're familar with Tcl some of the management going on
behind the scenes:

my $mw = MainWindow->new;
createEntries($mw);

my $f = $mw->Frame;
createEntries($f);

sub createEntries
{
my $f = shift;

for (my $i = 0; $i<3; $i++) {
my $e = $f->Entry;
print $e->PathName . "\n";
}
}

Should generate something like this:

..entry
..entry1
..entry2
..frame.entry
..frame.entry1
..frame.entry2


Anyway, there are several strategies you can use to access various
widgets. Instead of assigning each reference to the same variable, you
can could assign each reference to an array element, or a hash key. In
the past, I've used a widgets position within a grid to access it. I've
also walked the tree, or one level within the tree, by looping through a
widget's child elements.

Often, it's not necessary to have direct access to each widget.
Sometimes it's enough to maintain a reference to each Entry's value.
This is where developers leverage the -textvariable option.

When creating Composites it's common to advertise subwidgets by logical
names, which is really a variation of the assign widget to hash key
approach. I've even some code where the developer advertised subwidgets
of another widget. Kind of like this:

my $mw = MainWindow->new;
for (my $i = 0; $i<3; $i++) {
my $e = $mw->Entry;
my $entryLabel = "entry$i";
$mw->Advertise($entryLabel => $e);
print "$entryLabel => " .
$mw->Subwidget($entryLabel)->name . "\n";
}

Which yields the following, and shows you how the advertised name
differed from the name Tk assigned.

entry0 => entry
entry1 => entry1
entry2 => entry2

I wouldn't consider this a "Best Practice" though since by using it, I
could be unknowingly overriding important information internal to the
Widget and possibly crippling it.

Anyhow, hope some of that helps without muddying the waters too much more.

Rob


>
> For that matter, how would you click on an entrybox like the above, make
> an entry, and be able to tell some subroutine that the text has changed
> and which box was changed?
>
> Ok, so I am . (But, having a blast!) Just wish there were more
> books on TK, or that the Mastering Perl/TK book was larger:)
>
> Terkel

zentara

2005-05-01, 9:03 pm

On Thu, 28 Apr 2005 22:06:23 -0400, Terkel <terkxbaby182746@hooya.com>
wrote:

>The purpose of this question is learning rather than trying to actually
>build real code.
>The following code makes a row of entry boxes.
>
> for (my $i = 0; $i<12; $i++) {
> $entrybox = $mw->Entry(-width => 8, -textvariable =>
> \$entryarray[$i])->place(-x=>10 + ($i*70), -y=>25);
> }
>
>The only difference in any of the widgets is that the -textvariable is a
>different element in an array. No problem there, that works fine.
>
>What I don't understand is that it looks like I have built 12 identical
>boxes with the widget name of "$entrybox". How does TK know which one I
>am referring to?


Hi, just learn to use hashes...you will get the idea quickly after you
build a few hash tables. It makes it real easy to track things.

#!/usr/bin/perl
use warnings;
use strict;
use Tk;

my $mw = tkinit;

my %entry;

for (my $i = 0; $i<12; $i++) {

$entry{$i} = $mw->Entry(-width => 8,
-textvariable => $i

)->place(-x=>10 + ($i*70), -y=>25);
}

#then when you need to refer to them

$entry{2}->configure(-bg =>'lightskyblue');

MainLoop;
########################################
###############

One note, which can get tricky.
If you are going to get complicated( and you will later on), you have
to be careful how you assign the keys

For instance, what if you were making "meta-data" for each entry too.
You may run into a problem, where you are trying use the Tk::object as a
hash key.

So instead of
$entry{$i} = $mw->Entry(

You may need
$entry{$i}{'entry'} = $mw->Entry(
$entry{$i}{'somedata'} = $somedata

That way you can use $1, with more flexibility.

You may not understand it now, but you will the
first time you get hit with the error message
"Can't use Tk:object as a hash ref at line.....". :-)

You can make very complex guis in loops with hashes.

Like
my %frame

for (my $i = 0; $i<12; $i++) {

$frame{$i}{'label'} = $mw->Label(-width => 8,
-textvariable => \$i
)->pack;


$frame{$i}{'entry'} = $mw->Entry(-width => 8,
-textvariable => \$i
)->pack;

$frame{$i}{'text'} = $mw->Text( )->pack;

}


Then you can get at the second Text box with
my $text = $frame{2}{'text'}->get('1.0',end);



--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
Terkel

2005-05-01, 9:03 pm

On Thu, 28 Apr 2005 22:06:23 -0400, Terkel wrote:

> The purpose of this question is learning rather than trying to actually
> build real code.
>


Thanks both Rob and zentara.

I am beginning to see through the glass darkly and your replies really
helped. My original idea that perl was just an extended batch language
and that TK was a simple visual module has changed about 180 degrees:)

Terkel

Ala Qumsieh

2005-05-01, 9:03 pm

Terkel wrote:

> My original idea that perl was just an extended batch language
> and that TK was a simple visual module has changed about 180 degrees:)


I'm wondering where from and how did you get this idea in the first place?

Just curious :)
--Ala

Terkel

2005-05-01, 9:03 pm

On Sat, 30 Apr 2005 05:40:55 +0000, Ala Qumsieh wrote:

> Terkel wrote:
>
>
> I'm wondering where from and how did you get this idea in the first place?
>
> Just curious :)
> --Ala


Well, I have dinked around with scripts and scripting languages for years
but all my work has been in traditional compiler languages - Basic, C, and
finally Delphi/Pascal. Always thought of scripts as a way to do quick and
dirty stuff only, and thought Perl was just scripting on steroids.

I had a project (that I can't even remember what it was) that I had filled
up several pages of C++ code that wouldn't work. Then backed up and tried
it with Delphi. Still didn't work, or I should say, I didn't know how to
make it work.

Someone, probably on a newsgroup, mentioned that they had seen an example
of what I was trying to do in some "Learn Perl in 21 Minutes" type of
book. I found the book and was flabbergasted when I had the project
routine working in about 15 minutes and with only about 10 lines of code.

Back to the bookstore and came home with an armfull of Perl books. So
far, I am a LONG ways from guru-dom in Perl and TK but I have to say that
I wish I had found the language long ago. I love it.

Terkel

Martin Mohr

2005-05-04, 8:58 pm

Rob Seegel wrote:

> [interesting things]


nice, thank you!

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com