I need to change the entries in a Tk::Optionmenu widget whenever the user does something in another widget. No problem with that, but every time this happens, it triggers the Optionmenu widget's "-command" (callback) subroutine.

Of course, when the user actually clicks on the Optionmenu widget and selects one of the current menu items, this runs the callback with the menu value chosen by the user, and this is fine.

My problem is, how can the callback function tell the difference between being invoked by an actual menu selection (user has made a choice, so do something with that) vs. being invoked because the options have been changed (user hasn't really picked a specific option, so don't do anything yet).

Here's a little test script demonstrates the behavior: when the window first starts up, the first installation of options invokes the callback. Thereafter, the callback is invoked when the Optionmenu itself is used to make a selection, and each time the "Change Options" button is clicked.

I want the callback to be able to skip its work (or not be called in the first place) when installing a new menu. How do I do that?

#!/usr/bin/perl use strict; use Tk; my $mw = MainWindow->new(); my ($var, $tvar); my $opt = $mw->Optionmenu( -command => \&show_choice, -variable => \$var, -textvariable => \$tvar )->pack; change_ops( $opt ); my $f = $mw->Frame(-relief=>'groove', -borderwidth => 2)->pack; $f->Label(-textvariable=>\$tvar)->pack(-side => 'left'); $f->Label(-text => " -> ")->pack(-side => 'left'); $f->Label(-textvariable=>\$var)->pack(-side => 'left'); $mw->Button(-text=>'Change Options',-command=>[\&change_ops, $opt])->p +ack; $mw->Button(-text=>'Exit', -command=>sub{$mw->destroy})->pack; MainLoop; sub show_choice { print "got: ", shift, "\n" } sub change_ops { my $op = shift; my @newoptions = map { ++$. } ( 0 .. 3 ); $op->configure( -options => \@newoptions ); }
(the script is based loosely on the example provided in the Optionmenu man page, which also demonstrates the issue when it starts up)

I've looked at the source (Optionmenu.pm), and I could create a modified version of this widget, altering its "addOptions" and "setOption" functions so that the latter does not invoke the callback whenever it happens to be called by the former...

But creating a new version of a widget is the sort of thing I'm likely to do wrong the first few times I try, so I'm hoping some monk can guide me (actually, I'm hoping there's an easier work-around that I'm missing).


In reply to Setting options in Tk::Optionmenu without the callback? by graff

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.