Right click menu in Tcl/Tk

Few days back, I was looking for creating pop menu for a Tk object. After a lookup over internet I was able to able to create the right click pop-up menu. I thought of sharing same here. We will create a Text widget and use our mouse right click to display the text editing.

Binding Events:

Tk have a built in command bind which can be used to bind the x-events to the Tk window elements. Syntax for bind command is

bind tag ?sequence? ?+??script?

tag could be replace by the Widget name to bind the x-event. sequence signifies what events to connect to. We will be using the command shown below to bind the mouse events to a Tk window.

bind . <ButtonPress-1> {tk_messageBox -message "Left Button Clicked"}

Or replace ButtonPress-1 with 1

bind . <1> {tk_messageBox -message "Left Button Clicked"}

Creating Menu:

In Tk a pop up menu could be created using menu command. The syntax for menu command is

menu pathName ?options?

We will create a simple menu with two items in it. Code for creating menu is

menu .menu -tearoff 0
.menu add command -label "Copy"
.menu add command -label "Paste"

Displaying the menu:

The menu can be popped up using tk_popup command. We can invoke the menu created in last section by using command

tk_popup .menu $x $y

$x, $y denote the position to display the menu.

Getting the position of cursor:

Mouse cursor position can be obtained from %x and %y, but this value is with respect to the Tk window. However the arguments to the tk_popup are respective to the desktop window. So we will get the Tk window position with respect to the desktop window and add the cursor positions to them.

#Get mouse cursor relative to Tk window
set mx %x
set my %y
#Get window position
set x [winfo rootx .]
set y [winfo rooty .]
#Add to get absolute cursor position
set popupPosX [expr $x+$mx]
set popupPosY [expr $y+$my]

The complete Demo:

In the demo below, a text widget is used. The right click menu is associated with the text widget only. It can also be bound with the window or any other widget.

package require Tk

#Creating the menu
menu .menu -tearoff 0
.menu add command -label "Copy"
.menu add command -label "Paste"

#Creating the text area
text .t
scrollbar .sby -orient vert
pack .sby .t -expand yes -fill both -side right

#Creating binding
bind .t <3> {popupMenu .menu %x %y}

#A function to pop up the menu
proc popupMenu {theMenu theX theY} {
    set x [expr [winfo rootx .]+$theX]
    set y [expr [winfo rooty .]+$theY]
    tk_popup $theMenu $x $y

This completes the introduction to right click pop up menu creation in Tk.