arunmep has asked for the wisdom of the Perl Monks concerning the following question:

hai everybody my problem i want to create multiple widget at runtime say a number of buttons by using a loop.
while(@array) { $file=pop @array; $top->Button(-text => "Click Me",-command => sub{ system "start c:/WIN +NT/system32/notepad.exe $file" })->pack(); $x=$x+10; MainLoop; }
but i get only the last widget please suggest me a way

Edited by Chady -- replaced font tags with code tags.

Replies are listed 'Best First'.
Re: creating multiple widgets at runtime
by GrandFather (Saint) on Jul 25, 2005 at 03:50 UTC

    Move MainLoop; outside the while loop:

    while(@array) { $file=pop @array; $top->Button(-text => "Click Me",-command => sub{ system "start c:/W +INNT/system32/notepad.exe $file" })->pack(); $x=$x+10; } MainLoop;

    Note that c:/WINNT/system32/notepad.exe is not very portable. Use either Notepad $file or just $file (if $file has a .txt extension).


    Perl is Huffman encoded by design.
      thank you GrandFather i am able to get multiple widgets now but i need to have different control for each widget say by clicking each widget i need to open different files.how can i do that

        This works for me:

        use strict; use warnings; use Tk; my @array = ("File1.txt", "File2.txt", "File3.txt"); my $main = MainWindow->new (); while (@array) { my $name=pop @array; $main->Button ( -text => "Open $name", -command => sub{`notepad $name`} )->pack(); } MainLoop;

        Perl is Huffman encoded by design.
Re: creating multiple widgets at runtime
by greenFox (Vicar) on Jul 25, 2005 at 04:35 UTC

    I am just wondering if you had a good reason not to write that as:

    for my $file (@array){ #do some stuff with $file }

    ie. a non destructive iteration over @array...

    --
    Murray Barton
    Do not seek to follow in the footsteps of the wise. Seek what they sought. -Basho

Re: creating multiple widgets at runtime
by pg (Canon) on Jul 25, 2005 at 05:14 UTC

    You said "at runtime", which sort of indicating that you may not know what buttons you need at compilation time. If that is the case, the following example might be useful.

    use strict; use warnings; use Tk; my @files = ("File1.txt", "File2.txt", "File3.txt"); #in real life, th +is might not be fixed my @buttons; my $main = MainWindow->new(); my $load = $main->Button(-text => "Load", -command => \&load_buttons)- +>pack(); my $unload = $main->Button(-text => "Unload", -command => \&unload_but +tons)->pack(); MainLoop; sub load_buttons { for my $file (@files) { push @buttons, $main->Button(-text => "Open $file", -command = +> sub{`notepad $file`})->pack(); } } sub unload_buttons { while (@buttons) { my $button = pop @buttons; $button->destroy(); } }
Re: creating multiple widgets at runtime
by AReed (Pilgrim) on Jul 25, 2005 at 04:00 UTC
    You should call MainLoop after the while loop, not within it. I'm pretty sure that MainLoop should only be called once within a given Tk program.

      Just to clarify, this particular MainLoop should be removed not moved ;-)

      Not alltogether true. The following is ok and can be usefull:

      use strict; use warnings; use Tk; my $main = MainWindow->new (); $main->Button (-text => "Close", -command => sub{$main->destroy ();})- +>pack(); MainLoop; $main = MainWindow->new (); $main->Button (-text => "Close too", -command => sub{$main->destroy () +;})->pack(); MainLoop;

      Perl is Huffman encoded by design.
        Hmm, how could this be useful? Can't you do the same with a Toplevel and only one MainLoop?