• Using (dynamic) string variable as the label of menu

    From shenyeh.chen@gmail.com@21:1/5 to All on Thu Nov 18 07:47:31 2021
    Hi everyone,

    Is there anyway I can use (dynamic) string variable as the label of menu ? (created by menubutton, then add command -label).

    What I want to do, is change the label string of the pull-down menu according to some specific action or status.

    Any help is greatly appreciated.

    S-Y.Chen

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to shenye...@gmail.com on Thu Nov 18 16:48:13 2021
    shenye...@gmail.com <shenyeh.chen@gmail.com> wrote:
    Hi everyone,

    Is there anyway I can use (dynamic) string variable as the label of
    menu ? (created by menubutton, then add command -label).

    Yes, but you have to handle it yourself instead of setting a -variable
    or -textvariable option:

    package require lambda ;# install Tcllib to get 'lambda' package

    menubutton .mb -menu .mb.m -text "Menu Button"
    pack .mb

    menu .mb.m

    .mb.m add command -label xyz

    set ::thevar something

    trace add variable ::thevar write [lambda {w idx var _ _} {
    global $var
    $w entryconfigure $idx -label [set $var]
    } .mb.m 1]

    The magic is in the lambda attached to the trace. The trace provides
    an "event" signal that the variable is written into, and the code in
    the lambda takes care of reconfiguring the menu entry with the new
    value of the variable.

    Type the above into a console, then you can manually do "set thevar
    string" commands to see the menu entry label update.

    Note, if you want to use this often, it is probably best to create a
    wrapper proc to call that sets everything up.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Emiliano Gavilan@21:1/5 to Rich on Fri Nov 19 09:00:15 2021
    On Thu, 18 Nov 2021 16:48:13 -0000 (UTC)
    Rich <rich@example.invalid> wrote:

    shenye...@gmail.com <shenyeh.chen@gmail.com> wrote:
    Hi everyone,

    Is there anyway I can use (dynamic) string variable as the label of
    menu ? (created by menubutton, then add command -label).

    Yes, but you have to handle it yourself instead of setting a -variable
    or -textvariable option:

    package require lambda ;# install Tcllib to get 'lambda' package

    menubutton .mb -menu .mb.m -text "Menu Button"
    pack .mb

    menu .mb.m

    .mb.m add command -label xyz

    set ::thevar something

    trace add variable ::thevar write [lambda {w idx var _ _} {
    global $var
    $w entryconfigure $idx -label [set $var]
    } .mb.m 1]

    The magic is in the lambda attached to the trace. The trace provides
    an "event" signal that the variable is written into, and the code in
    the lambda takes care of reconfiguring the menu entry with the new
    value of the variable.

    Type the above into a console, then you can manually do "set thevar
    string" commands to see the menu entry label update.

    Note, if you want to use this often, it is probably best to create a
    wrapper proc to call that sets everything up.


    A powerful approach is to combine the use of lambda and hook packages from tcllib. This allow highly dynamic interfaces to be set with ease.
    This short example shows how to dynamically change a label when a program connect or disconnects from a communications endpoint

    package require lambda
    package require hook

    # here is our subject: the Comm(unication) "module"
    proc connect {} {
    # do the connection; if successful then
    hook call Comm <<Connect>> 1
    }
    proc disconnect {} {
    # disconnect
    hook call Comm <<Connect>> 0
    }

    #build the menu
    set m [menu .m]
    set idx [$m add command -label Connect -command connect]

    # set the observer
    hook bind Comm <<Connect>> $m [lambda {mnu idx connected} {
    if {$connected} {
    $mnu itemconfigure $idx -label Disconnect -command disconnect
    } else {
    $mnu itemconfigure $idx -label Connect -command connect
    }
    } $m $idx]
    # if you remove the menu, clean up the observer
    bind $m <Destroy> "hook forget %W"

    You can have an arbitrary number of observers por any subject.
    Consult the man pages for further info.

    Regards

    Emiliano

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)