Diego Henrique
Diego Henrique

Reputation: 255

I am need select a option at the tk_menuOption and after invoke um event

What I want is for it to fire the event bind to each choice made.

So I will not use a button to call any event.

This is my The doubt:

set choice [list \
{News} \
{Nature} \
{City} \
{Food} \
{People} \
{Anime} \
{Tecnology} \
{Objects} \
{Others}]

tk_optionMenu . chose {*}$choice

bind . <1> { 
    clipboard clear
    clipboard append [%W cget -text]
    bell
    # Procedure to be invoke, this bellow:
    load
}
   
proc load { } {
   # Code here!
   tk_messageBox -message "You picked the option: $chose"
}

How to can I have some a event bind for tk_optionMenu, since that I can change first each option so to after do call procedure.

As in bind . <1>, there is no time to choose. Then, it is triggered by clicking on tk_menuOption.

I even tried to switch to other properties of the bind itself, but I didn't get the expected result.

I think something is missing to make it work as proposed in the question. I think it must be a stopwatch, which waits a few milliseconds before calling the event. This is what I imagine.

Upvotes: 0

Views: 265

Answers (3)

Schelte Bron
Schelte Bron

Reputation: 4813

While the tk_menuOption does not provide a binding for when an option is selected, it has an associated variable. So you can put a trace on that variable and do whatever you want in the handler:

trace add variable chose write {apply {{name arg op} {
    upvar 1 $name var
    clipboard clear
    clipboard append $var
    bell
    # Procedure to be invoked
    load
}}}

Note: It is not a good idea to overwrite built-in commands, like load. It is likely to break a lot of things.

Upvotes: 1

Diego Henrique
Diego Henrique

Reputation: 255

Even though we already have the answers as good solutions that this problem addresses.

Before I even received the answer, everyone found this link - https://wiki.tcl-lang.org/page/tk_optionMenu

The description of the "snippet" in the link is as follows:

tk_optionMenu $w varName a b c d 
for {set i 0} {$i < [[$w cget -menu] index end]} {incr i} {
    [$w cget -menu] entryconfig $i -command $cmd 
}

That was the discovery of the answer to solve my problem. So, I want to share with friends:

My Example:

#!/bin/sh
# \
exec wish "$0" "$@"

package require Tk

. configure -width 300 -height 200

set choice [list \
{News} \
{Nature} \
{City} \
{Food} \
{People} \
{Anime} \
{Tecnology} \
{Objects} \
{Others} ]

tk_optionMenu .foo chose {*}$choice

for {set i 0} {$i < [[.foo cget -menu] index end]} {incr i} {
    [.foo cget -menu] entryconfig $i -command {load;bell}
}
   
proc load { } {
global chose
    # Code here!
    tk_messageBox -message "You picked the option: $chose"
}

pack .foo -side left -fill both -expand 1
.foo config -indicatoron 0 -relief flat -justify center -bg white

Print:

enter image description here

But, the answers given by them .. Schelte Bron and Donal Fellows, were big help. Now I learn more things that I didn't know before. Since the words load are embedded in Tcl, it is not a good idea to use them.

Upvotes: 0

Donal Fellows
Donal Fellows

Reputation: 137567

First off, tk_optionMenu is just a procedure. Here's the source for it, but it's really quite short:

proc ::tk_optionMenu {w varName firstValue args} {
    upvar #0 $varName var

    if {![info exists var]} {
        set var $firstValue
    }
    menubutton $w -textvariable $varName -indicatoron 1 -menu $w.menu \
            -relief raised -highlightthickness 1 -anchor c \
            -direction flush
    menu $w.menu -tearoff 0
    $w.menu add radiobutton -label $firstValue -variable $varName
    foreach i $args {
        $w.menu add radiobutton -label $i -variable $varName
    }
    return $w.menu
}

If it doesn't do what you want, just take the code and modify it.

Secondly, events on menus are really tricky! In particular, if you are on Windows or macOS then many standard events are not delivered at all due to the way that their native menuing system works. Instead, you get two possible, useful callbacks:

  1. The -command callback on the menu items; this is supported by most of the menu items, especially including all the ones which end an interaction session with the menu (such as command items and radiobutton items).
  2. The -postcommand callback on the overall menu which is called when the menu is posted to the screen, giving you an opportunity to alter the contents of the menu dynamically (if you need it).

If what you want can't be done with those, it probably shouldn't be done with a menu in the first place as the interaction pattern with menus is pretty strongly fixed. A listbox might be more suitable? Or something custom (you often can do those with a text or canvas; no C required).

Upvotes: 1

Related Questions