thank you very much Ken. This works fine, however, I have a few more questions:
1) I don't understand what this does:
# Insert our "selectable" bindtag at the
# beginning of the bindtag path for the
# frame.
bindtags .f$i [linsert [bindtags .f$i] 0 selectable]
# Uncomment the following lines if you
# want the frame toggling binding active
# for the contents of the frame as well.
# bindtags .f$i.r [linsert [bindtags .f$i.r] 0 selectable]
# bindtags .f$i.b [linsert [bindtags .f$i.b] 0 selectable]
2) I had to add this at the beginning of my script for the selection to work
bind . <ButtonPress-1> {
FrameSelect %W
}
What does this do?
# Create a symbolic bindtag called
# "selectable", that invokes our FrameSelect
# procedure in response to a left-click.
bind selectable <ButtonPress-1> {
FrameSelect %W
}
3)
The problem I have now is that my frame is not scrollable. I found an old post of yours explaining how to do this. I can't get it to work, what am I doing wrong (see code posted below)?
#!/usr/local/bin/wish
#exec wish "$0" "$@"
#-----------------------------------------------------------------------------
###############
# ZMAP MACRO BUILDER
#
# AUTHOR: Fabien Coutel
#
# Last Modified : Wed Sep 25 13:15:39 BST 2002
##################################################
# set global variables
##############################
frame .top -borderwidth 2
pack .top -fill x
#
# LGC LOGO
#
set i [image create photo -file lgc_logo.gif ]
#set logo [checkbutton .top.but -image $i -selectcolor SeaGreen1]
#pack .top.but -expand yes
#
#MENUS
#
#
#MENUS
#
menu .top.menuBar -tearoff 0
set f .top.menuBar.file
set fc .top.menuBar.func
set h .top.menuBar.help
set edit .top.menuBar.edit
#logo
.top.menuBar add command -image $i -command {}
#File menu
.top.menuBar add cascade -menu $f -label "File" -font {Helvetica 14 bold} -underline 0
menu $f -tearoff 1
$f add command -label "New" -font {Helvetica 12 bold} -underline 0 -command {}
$f add command -label "Open" -font {Helvetica 12 bold} -underline 0 -command {}
$f add command -label "Save" -font {Helvetica 12 bold} -underline 0 -command {}
$f add separator
$f add command -label "Exit" -font {Helvetica 12 bold} -underline 1 -command {exit} -accelerator "Meta-q"
#Edit
.top.menuBar add cascade -menu $edit -label "Edit" -font {Helvetica 14 bold} -underline 0
menu $edit -tearoff 1
$edit add command -label "Add before" -font {Helvetica 12 bold} -underline 0 -command {}
$edit add command -label "Add after" -font {Helvetica 12 bold} -underline 0 -command {}
$edit add command -label "Delete" -font {Helvetica 12 bold} -underline 0 -command {}
#Functions
.top.menuBar add cascade -menu $fc -label "Functions" -font {Helvetica 14 bold} -underline 0
menu $fc -tearoff 1
$fc add command -label "Import" -font {Helvetica 12 bold} -underline 0 -command {}
#help menu
.top.menuBar add cascade -menu $h -label "Help" -font {Helvetica 14 bold} -underline 0
menu $h -tearoff 1
$h add command -label "About.." -font {Helvetica 12 bold} -command {About} -underline 0
global f h fc edit
# bind accelerator keys
bind . <Meta-q> {exit}
# for frame select
bind . <ButtonPress-1> {
FrameSelect %W
}
. configure -menu .top.menuBar
# main window
#
wm title . "ZMAP MACRO BUILDER"
wm geometry . 80x20
####
#frames
# for buttons
frame .btfr -borderwidth 10
pack .btfr -side top -fill x -expand 0
# create canvas to put flows
# Use Canvas to implement scrollable frame
canvas .c -height 100 -width 50 -yscrollcommand {.sb set}
scrollbar .sb -orient vertical -command {.c yview}
# frame that holds flows
frame .c.fcfr -borderwidth 2 -relief sunken
# Tell the canvas to display the frame, anchoring the
# upper-left hand corner of the frame in the upper-left
# hand corner of the canvas
#.c create window 0 0 -anchor nw -window .c.fcfr
# Use grid to display the canvas, the scrollbar, and the
# close button in the toplevel window. Handle resizing properly.
grid .c -row 0 -column 0 -sticky nsew -pady 4 -padx 2
grid .sb -row 0 -column 1 -sticky ns -pady 4 -padx 2
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1
# Detect <Configure> events on the frame to detect when
# it is first displayed and any time is is resized.
# In either case, recompute the visible bounds of the
# canvas and update its -scrollregion attribute.
bind .c.fcfr <Configure> {
.c configure -scrollregion [.c bbox all]
}
##
###
#function frame
set incfr 0
# Initialize a counter to help us create
# unique frame names on demand.
set frameCounter [incr incfr]
global incfr frameCounter
#
# Action Buttons
#
set but [button .btfr.run -background #88ff88 -activebackground #88ff88 -text "Run" -command Run]
button .btfr.quit -background #ffbbbb -activebackground #ffbbbb -text "Quit" -command exit
pack .btfr.run -side left -padx 100
pack .btfr.quit -side left
#
# Lower frame holds text output
#
frame .logfr
set log [text .logfr.log -width 50 -height 5 -borderwidth 3 -relief sunken -setgrid true -yscrollcommand {.logfr.scroll set} -font {courier 9}]
scrollbar .logfr.scroll -command {.logfr.log yview}
pack .logfr.scroll -side right -fill y
pack .logfr.log -side left -fill both -expand true
pack .logfr -side top -fill both -expand true
###########
# FUNCTIONS
############
###
# MAKE PROCESS FRAME
###
proc MakeFrame {w} {
# make frame
frame $w -borderwidth 4
pack $w -side top -fill x
#checkbutton
checkbutton $w.cb -text "Empty " -variable dummy -command {} -padx 10
#button
button $w.b -text "Parameters..." -width 10 -command {} -padx 20
pack $w.cb $w.b -padx 2 -pady 2 -side left
}
##################################
# FrameSelect
#
# Called by a binding to select a frame.
##################################
proc FrameSelect {w} {
global selected
puts "in FrameSelect"
# If the user clicked on a child widget
# rather than its parent frame, cycle up
# to the parent frame. Note that this
# simple algorithm *doesn't* allow for
# another frame to be nested in our
# containing frame. It also relies on you
# not changing the frame's class to
# anything other than "Frame" to work
# properly.
while {([winfo class $w] != "Frame"

&& ("$w" != "."

} {
set w [winfo parent $w]
}
# "De-select" whatever is currently
# selected. This also handles "toggling"
# an already selected frame by clicking on
# it again.
if {[info exists selected(current)]} {
$selected(current) configure -relief $selected(relief)
}
#if {[info exists selected(current)]
#&& ($selected(current) == $w)} {
# The user clicked on the frame already
# selected. Simply "de-select" the frame
# and return.
#unset selected(current)
#return
#} else {
# Highlight the selected frame by
# changing its border to groove. To be
# visible, the frame must have its
# border width (-bd) set to a value
# greater than 2.
set selected(relief) [$w cget -relief]
set selected(current) $w
$w configure -relief groove
#}
}
# Create a symbolic bindtag called
# "selectable", that invokes our FrameSelect
# procedure in response to a left-click.
bind selectable <ButtonPress-1> {
FrameSelect %W
}
##################################
# InsertFrame
#
# Create a frame on demand. If another frame
# is selected, the new frame is packed
# before the selected frame; otherwise, the
# new frame is packed after all existing
# frames.
##################################
proc InsertFrame {} {
global selected
global frameCounter
set i [incr frameCounter]
set f .fcfr.fr$i
MakeFrame $f
# Insert our "selectable" bindtag at the
# beginning of the bindtag path for the
# frame.
bindtags $f [linsert [bindtags $f] 0 selectable]
# Uncomment the following lines if you
# want the frame toggling binding active
# for the contents of the frame as well.
# bindtags $f.cb [linsert [bindtags $f.cb] 0 selectable]
# bindtags $f.b [linsert [bindtags $f.b] 0 selectable]
#pack $f.cb -padx 2 -pady 2 -anchor w
#pack $f.b -padx 2 -pady 2
if {[info exists selected(current)]} {
# If a frame is selected, insert the new
# frame in front of the selected one in
# the packing order.
pack $f -before $selected(current) -padx 2 -pady 2 -fill x
} else {
# If no frame is selected, pack the new
# frame after all other frames.
pack $f -padx 2 -pady 2 -fill x
}
}
##################################
# DeleteFrame
#
# Delete the currently selected frame. If no
# frame is selected, nothing happens.
##################################
proc DeleteFrame {} {
global selected
if {[info exists selected(current)]} {
destroy $selected(current)
unset selected(current)
}
}
# Define virtual events, which allows us to
# use mutiple bindings to perform the same
# task.
event add <<Insert>> <Control-KeyPress-a> <KeyPress-Insert>
event add <<Delete>> <Control-KeyPress-d> <KeyPress-Delete>
# Bind to the toplevel window, so that these
# bindings are active no matter which widget
# has focus.
bind . <<Insert>> InsertFrame
bind . <<Delete>> DeleteFrame
###### MAIN #########
#set first frame (default)
set fu .c.fcfr.fr$incfr
#display first frame (default)
MakeFrame $fu
Thanks so much!