简体   繁体   中英

Perl IUP GUI Button Action with uni parameter set

I'm using the Perl IUP module implemented by kmx , I liked it due to ease of using it and somewhat ok look.

I need to create a Frame box with multiple button from a list (lets say 40-50). I can create this easily in a for loop going through the array ( double Array, containing "Name" and value for each row ) `

my @ChildsSetOfButtons=();
foreach $array (@ITEMNAME)
{
    $tempButton = IUP::Button->new( TITLE=>$array->[2],
                SIZE=>"50x20", FONTSTYLE=>'bold',FONTSIZE=>"10");
    $tempButton->ACTION( sub {selOrder($array->[3]); });
}
push(@ChildsSetOfButtons,$tempButton); 
my $tableOfButton = IUP::Frame->new( TITLE=>"Items",child=>
                IUP::GridBox->new( child=> [@ChildsSetOfButtons], NUMDIV=>4, 
                ORIENTATION=>"HORIZONTAL"), MARGIN=>"5x5",
                EXPANDCHILDREN =>"YES",GAPLIN=>10, GAPCOL=>10);

Well the Buttons appear in the GUI beautifully in a nice grid. Now my problem is, how I can send the individual unique values from each Button actions? I understand that the the values are statically linked at the time of creation of the button.

but somehow this similar implementation I could get it working in the PerlTK, Since I started with this IUP, I don't want to go back to TKperl and start writing my whole GUI from sratch. `

foreach my $array (@ITEMNAME)
{
    $fr2->Button(-text=>$array->[2],
                 -padx => 6,
                 -font => ['arial', '10', 'normal'],
                 -foreground  => 'blue',
                 -command => [\&writeUARTDirect,$array->[3]],
                )->pack(-side=>'bottom');
}

` How can I get it worked in the perl-IUP framework? Can anyone tell me a trick? :)

There are some issues with your example. I added a bit to make it runnable:

use IUP ':all';
use strict;
use warnings;
use v5.30;

my @ITEMNAME = ([0,0,foo=>'btn_foo'],
                [0,0,bar=>'btn_bar']
                );
my @ChildsSetOfButtons=();
foreach my $array (@ITEMNAME)
{
    my $tempButton = IUP::Button->new(
                                      TITLE=>$array->[2],
                                      SIZE=>"50x20",
                                      FONTSTYLE=>'bold',
                                      FONTSIZE=>"10");

    # alternative: copied value
    # my $value = $array->[3];
    # $tempButton->ACTION( sub {selOrder($value); });

    $tempButton->ACTION( sub {selOrder($array->[3]); });

    push(@ChildsSetOfButtons,$tempButton);

}
my $tableOfButton = IUP::Frame->new(
                TITLE=>"Items",
                child=>
                    IUP::GridBox->new( child=> [@ChildsSetOfButtons],
                                       NUMDIV=>4, 
                                       ORIENTATION=>"HORIZONTAL"),
                MARGIN=>"5x5",
                EXPANDCHILDREN =>"YES",
                GAPLIN=>10,
                GAPCOL=>10);
my $dlg = IUP::Dialog->new( TITLE=>"Test Dialog",
                            MARGIN=>"10x10",
                            child=> $tableOfButton,);

# Do you want changes like these being reflected in the callback?
$ITEMNAME[1]->[3] = 'another_value';
$ITEMNAME[0] = [];    

$dlg->Show;

IUP->MainLoop;

sub selOrder{
    my $val = shift;
    say "you pressed $val";
}

I added strict and made your variables lexical. You were creating the buttons in a loop but the push statement was outside of the loop. So your buttons were not added to @ChildsSetOfButtons .

Your callback sub references $array->[3] which is an alias into @ITEMNAME this might lead to unintended side effects if the values in @ITEMNAME are changed. You can avoid that by copying the value into a lexical variable inside the loop and use that in your callback. This way you get a closure with the value decoupled from @ITEMNAME .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM