perl tk - pass function inside button

Discussion in 'Perl Misc' started by Slickuser, Apr 28, 2009.

  1. Slickuser

    Slickuser Guest

    I have this generic function to add a button to the main Tk window.
    How do I pass this correction function in when a button is press for
    this Button?

    add_button('test a',1,0,\&test_a);
    add_button('test b',1,1,\&test_b);

    sub add_button ( $$$$)
    {
    my ($text,$row,$col,$cmd) = @_;
    $main->Button
    (
    -text => $text,
    -command =>\&function_pass
    ## pass in user command?
    ##\&test_a
    ### \&test_b
    )
    ->grid
    (
    -row => $row,
    -column => $col
    );
    }
    Slickuser, Apr 28, 2009
    #1
    1. Advertising

  2. Slickuser <> wrote in news:8703c486-548f-44e0-a181-
    :

    > I have this generic function to add a button to the main Tk window.
    > How do I pass this correction function in when a button is press for
    > this Button?


    I can't make sense of this paragraph no matter how many times I read it.

    > add_button('test a',1,0,\&test_a);
    > add_button('test b',1,1,\&test_b);
    >
    > sub add_button ( $$$$)


    Why are you using a prototype?

    > {
    > my ($text,$row,$col,$cmd) = @_;
    > $main->Button
    > (
    > -text => $text,
    > -command =>\&function_pass
    > ## pass in user command?
    > ##\&test_a
    > ### \&test_b
    > )


    Shouldn't you be referring to the fourth argument passed to add_button
    (which is in $cmd)? What the heck is function_pass?

    Sinan

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://www.rehabitation.com/clpmisc/
    A. Sinan Unur, Apr 28, 2009
    #2
    1. Advertising

  3. Slickuser

    Slickuser Guest

    I have a lot of buttons and each button have different function call
    (once clicked).

    I created a generic sub routine to create the button and grab inputs
    from method call.
    Now I want to pass in a "sub routine" so this button will execute the
    right method call once a button is click.

    Thanks.

    On Apr 28, 2:51 pm, "A. Sinan Unur" <> wrote:
    > Slickuser <> wrote in news:8703c486-548f-44e0-a181-
    > :
    >
    > > I have this generic function to add a button to the main Tk window.
    > > How do I pass this correction function in when a button is press for
    > > this Button?

    >
    > I can't make sense of this paragraph no matter how many times I read it.
    >
    > > add_button('test a',1,0,\&test_a);
    > > add_button('test b',1,1,\&test_b);

    >
    > > sub add_button ( $$$$)

    >
    > Why are you using a prototype?
    >
    > > {
    > >      my ($text,$row,$col,$cmd) = @_;
    > > $main->Button
    > >      (
    > >           -text          => $text,
    > >           -command      =>\&function_pass
    > >           ## pass in user command?
    > >               ##\&test_a
    > > ### \&test_b
    > >      )

    >
    > Shouldn't you be referring to the fourth argument passed to add_button
    > (which is in $cmd)? What the heck is function_pass?
    >
    > Sinan
    >
    > --
    > A. Sinan Unur <>
    > (remove .invalid and reverse each component for email address)
    >
    > comp.lang.perl.misc guidelines on the WWW:http://www.rehabitation.com/clpmisc/
    Slickuser, Apr 28, 2009
    #3
  4. Slickuser

    Guest

    On Tue, 28 Apr 2009 10:39:29 -0700 (PDT), Slickuser <> wrote:

    >I have this generic function to add a button to the main Tk window.
    >How do I pass this correction function in when a button is press for
    >this Button?
    >

    [untested]

    sub add_button
    {
    my ($text, $row, $col, $func_ref) = @_;
    $main->Button
    (
    -text => $text,
    -command => [\&function_pass, $func_ref],
    )
    ->grid
    (
    -row => $row,
    -column => $col
    );
    }

    sub function_pass
    {
    my $func = shift;
    $func->();
    }

    add_button('test a',1,0,\&test_a);
    add_button('test b',1,1,\&test_b);


    -----------------------------------
    References:
    http://oreilly.com/catalog/mastperltk/chapter/ch15.html
    http://oreilly.com/catalog/lperltk/chapter/ch02.html

    You should re-read all the chapters.
    I'm pretty sure you haven't a clue as to even what a frame windows is.

    -sln
    , Apr 29, 2009
    #4
  5. Slickuser <> wrote in
    news::

    [ don't top post. don't quote sigs. read and follow the posting
    guidelines already ]

    > On Apr 28, 2:51 pm, "A. Sinan Unur" <> wrote:
    >> Slickuser <> wrote in
    >> news:8703c486-548f-44e0-a181-
    >> :
    >>
    >> > I have this generic function to add a button to the main Tk window.
    >> > How do I pass this correction function in when a button is press
    >> > for this Button?

    >>
    >> I can't make sense of this paragraph no matter how many times I read
    >> it.
    >>
    >> > add_button('test a',1,0,\&test_a);
    >> > add_button('test b',1,1,\&test_b);

    >>
    >> > sub add_button ( $$$$)

    >>
    >> Why are you using a prototype?
    >>
    >> > {
    >> >      my ($text,$row,$col,$cmd) = @_;
    >> > $main->Button
    >> >      (
    >> >           -text          => $text,
    >> >           -command      =>\&function_pass
    >> >           ## pass in user command?
    >> >               ##\&test_a
    >> > ### \&test_b
    >> >      )

    >>
    >> Shouldn't you be referring to the fourth argument passed to
    >> add_button (which is in $cmd)? What the heck is function_pass?
    >>

    > I have a lot of buttons and each button have different function call
    > (once clicked).
    >
    > I created a generic sub routine to create the button and grab inputs
    > from method call.
    > Now I want to pass in a "sub routine" so this button will execute the
    > right method call once a button is click.


    You still haven't explained what exactly is giving you a problem and why
    you are using prototypes.

    I was assuming you understood what function arguments are etc in my
    original response but it looks like that's where the problem lies.

    So, is this (not tested) really what you are asking for?

    sub add_button {
    my ($text, $row, $col, $cmd) = @_;

    $main->Button(
    -text => $text,
    -command => $cmd,
    )->grid(
    -row => $row,
    -column => $col,
    );
    }

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://www.rehabitation.com/clpmisc/
    A. Sinan Unur, Apr 29, 2009
    #5
  6. A. Sinan Unur <> wrote:
    > Slickuser <> wrote in
    > news::
    >
    > [ don't top post.



    Message-ID: <>


    >> On Apr 28, 2:51 pm, "A. Sinan Unur" <> wrote:
    >>> Slickuser <> wrote in
    >>> news:8703c486-548f-44e0-a181-
    >>> :


    >>> > sub add_button ( $$$$)


    >>> Why are you using a prototype?


    > You still haven't explained what exactly is giving you a problem and why
    > you are using prototypes.



    Message-ID: <>


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
    Tad J McClellan, Apr 29, 2009
    #6
  7. Slickuser <> wrote:
    >I have a lot of buttons and each button have different function call
    >(once clicked).
    >
    >I created a generic sub routine to create the button and grab inputs
    >from method call.
    >Now I want to pass in a "sub routine" so this button will execute the
    >right method call once a button is click.


    Let me try to rephrase the way I understand your question:
    You got a subroutine A and you want to pass other subroutines X, Y, Z,
    .... to that subroutine as a parameter. Is this correct?

    You cannot do that directly. In Perl subroutine parameters must be
    scalars and subroutines are not scalars.
    However nothing is stopping you from passing a reference to the other
    subroutine(s) because references are scalars, too.

    [Bottom quote snipped, please don't do that]]

    jue
    Jürgen Exner, Apr 29, 2009
    #7
  8. Slickuser

    Guest

    On Wed, 29 Apr 2009 01:00:11 GMT, "A. Sinan Unur" <> wrote:

    >Slickuser <> wrote in
    >news::
    >
    >[ don't top post. don't quote sigs. read and follow the posting
    >guidelines already ]
    >
    >> On Apr 28, 2:51 pm, "A. Sinan Unur" <> wrote:
    >>> Slickuser <> wrote in
    >>> news:8703c486-548f-44e0-a181-
    >>> :
    >>>
    >>> > I have this generic function to add a button to the main Tk window.
    >>> > How do I pass this correction function in when a button is press
    >>> > for this Button?
    >>>
    >>> I can't make sense of this paragraph no matter how many times I read
    >>> it.
    >>>
    >>> > add_button('test a',1,0,\&test_a);
    >>> > add_button('test b',1,1,\&test_b);
    >>>
    >>> > sub add_button ( $$$$)
    >>>
    >>> Why are you using a prototype?
    >>>
    >>> > {
    >>> >      my ($text,$row,$col,$cmd) = @_;
    >>> > $main->Button
    >>> >      (
    >>> >           -text          => $text,
    >>> >           -command      =>\&function_pass
    >>> >           ## pass in user command?
    >>> >               ##\&test_a
    >>> > ### \&test_b
    >>> >      )
    >>>
    >>> Shouldn't you be referring to the fourth argument passed to
    >>> add_button (which is in $cmd)? What the heck is function_pass?
    >>>

    >> I have a lot of buttons and each button have different function call
    >> (once clicked).
    >>
    >> I created a generic sub routine to create the button and grab inputs
    >> from method call.
    >> Now I want to pass in a "sub routine" so this button will execute the
    >> right method call once a button is click.

    >
    >You still haven't explained what exactly is giving you a problem and why
    >you are using prototypes.
    >
    >I was assuming you understood what function arguments are etc in my
    >original response but it looks like that's where the problem lies.
    >
    >So, is this (not tested) really what you are asking for?
    >
    >sub add_button {
    > my ($text, $row, $col, $cmd) = @_;
    >
    > $main->Button(
    > -text => $text,
    > -command => $cmd,
    > )->grid(
    > -row => $row,
    > -column => $col,
    > );
    >}


    What??? I'm not sure you understood his pigeon Engrish. His example code clearly
    portray's his intended question. He's looking for a single *pass-through* function
    handler for all the buttons he creates in a particular group of buttons.

    That is the \&function_pass handler. In the add_button function he is instantiating
    a new button. Each call is assigning the same button handler for every new button.

    In the add_button function, he is trying to add a parameter to be passed to a common
    handler. In this case its a reference to a function. But it could have been anything,
    like a pseudo button ID.

    When instantiating a Button, the -command parameter expects either a code ref or an
    array ref. The latter must have a code ref as the first parameter, then any number of
    user, pre-defined arguments that are passed to that function. This emulate's
    a sophisticated event driven OS, gui or otherwise, and is just an emulation.

    Sometimes develpers want to 'pre-filter' events instead of asigning unique handlers
    to each events. Sometimes there is a range of events that need action en-mass like
    disabling or enabling or other factored out chores.

    This is quite common in event driven OS applications.

    -command => $code_ref or [$code_ref, $arg1, $arg2, ...],

    And it is quite common to have a single handler for many buttons, needing only the
    button ID (pseudo in this case).

    I think you are looking at the trees instead of the forest.
    There are numerous uses for a common handler in event driven app's.
    Even primitive Tk apps.

    ------------------------
    sub function_pass
    {
    my ($func, $id) = @_;
    # do common activities
    # ...
    # call this specific handler
    my $result = $func->();
    # do specific activities
    # if ($id == 2 && !$result)
    # { .. disable a group of controls .. }
    }

    sub add_button
    {
    my ($text, $row, $col, $handler, $control_id) = @_;
    # instatiate button, set grid
    $main->Button (
    -text => $text,
    -command => [\&function_pass, $handler, $control_id]
    )->grid(
    -row => $row,
    -column => $col,
    );
    }

    sub test_a
    {
    }
    sub test_b
    {
    }

    add_button('test a', 1,0, \&test_a, 1);
    add_button('test b', 1,1, \&test_b, 2);

    -----------------------
    -sln
    , Apr 29, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page