330 likes | 530 Views
Outline Basic Structures Widget Creation Geometry Management Widget Commands Event Bindings Interprocess Communication Misc. Commands Examples Goal Understand Tk syntax Understand Tk built-in commands Reading Ch. 19-31, Practical Programming in Tcl and Tk.
E N D
Outline Basic Structures Widget Creation Geometry Management Widget Commands Event Bindings Interprocess Communication Misc. Commands Examples Goal Understand Tk syntax Understand Tk built-in commands Reading Ch. 19-31, Practical Programming in Tcl and Tk Building User Interfaces with Tk/Tcl
1. Widget hierarchy 2. One Tcl interpreter 3. One process can have > 1 application in a process Widget = window with particular look and feel Widget classes implemented by Tk frame, toplevel label, button, checkbutton, radiobutton menu, menubutton message, dialog entry, text, listbox canvas scrollbar, scale Structure of a Tk Application
The Widget Hierarchy . .listbox .menu .scroll .menu.file .menu.help
Types of Windows Top-level window Main window . .dlg .listbox .menu .scroll .menu.file .menu.help .dlg.msg .dlg.no .dlg.yes Internal windows
Each widget has a class: button, listbox, etc. Tcl command named after each class, used to create instances button .a.b -text Quit -command exit scrollbar .x -orient horizontal Creating Widgets class name configuration options window name
Defined by class for buttons: activeBackground, activeForeground, anchor, background, bitmap, borderWidth, command, cursor, disableForeground, font, foreground, height, padx, pady, relief, state, text, textVariable, width If not specified on command line, taken from option database loaded from RESOURCE_MANAGER property or .Xdefaults file may be set, queried with Tcl commands option add *Button.relief sunken If not in option database, use default provided by class implementation Configuration Options
Widgets do not control their own positions and sizes, geometry managers do Widgets do not appear on screen until managed by geometry manager Geometry manager = algorithm for arranging slave windows relative to master window Parameters from application designer Geometry of master Requested size from slave Geometry Manager Size and location of slave Requested size for master Geometry Management
Simple, but not very powerful Each slave placed individually relative to its master The Placer place .x -relx 0.5 \ -y 1.0c -anchor n place .x -x 0 -y 0 place .x -relx 0.5 -rely 0.5 \ -height 3c -anchor center place .x -relheight 0.5 \ -relwidth 0.5 -relx 0 -rely 0.5
Much more powerful than placer Arranges groups of slaves together Packs slaves around edges of master’s cavity For each slave in order: 1. Pick a side of the master 2. Slice off a frame for slave 3. Possibly grow slave to fill frame 4. Position slave in frame The Packer
Packer Examples pack .a -side left pack .b -side left pack .c -side left .a .b .c .a .b .c • pack .a -side top -anchor w • pack .b -side top -anchor w \ • -pady .5c • pack .c -side top -anchor w .a .b .a .b .c .c • pack .a -side top -fill x • pack .b -side right -fill y • pack .c -padx 0.5c -pady 1c \ • -fill both .a .c .b .b .c .a
Considers relationships between slaves constraint-like placement row and column arrangements easy to achieve adjusts arrangement if slave requests a different size Requests size on behalf of master just large enough for all slaves adjusts if slaves request different sizes permits hierarchical geometry management constrains propagate in hierarchy Packer Advantages
Tcl command for each widget, named after widget’s path name created with widget Used to reconfigure, manipulate widget button .a.b .a.b configure -relief sunken .a.b flash scrollbar .x .x set 0.2 0.4 .x get Widget command deleted automatically when widget is destroyed Principle: all state should be readable, modifiable, anytime Widget Commands
Question: How to make widgets work together with application, other widgets? Answer: Tcl commands Widget actions are Tcl commands button .a.b -command exit Widgets use Tcl commands to communicate with each other scrollbar .x -command “.y yview” Application uses widget commands to communicate with widgets Connections button release exit click on arrow .y yview 9
Associate Tcl with mouse/keyboard events bind .t <Control-h> {backspace .t} Can select one or more windows single window: .t all windows in a class: Text all windows: all Specifying events <Double-Control-ButtonPress-1> <3> <Any-KeyPress> Bindings Window/Tag Event Sequence Script Event Type Button or Keysym Modifiers
% substitutions in binding scripts coordinates from event: %x and %y window: %W character from event: %A etc. Examples bind .c <B1-Motion> {move %x %y} bind .t <Any-KeyPress> {insert %A} bind all <Help> {help %W} Only one binding triggers from each event for each tag/window in order window before class before toplevel before all if >1 binding with same tag match, most specific executes Bindings (cont.)
Binding tags event not bound to window, class, or all is bound to a tag any user-defined string every window has list of binding tags apply event to each tag in order most specific binding that matches tag/event is executed Default window name, class name, nearest toplevel ancestor name, all bindtags window ?tagList? can read/modify tag list for window add new bindings, modify order bindtags .b {all . Button .b} - reverse default order Use to manage complex binding sets Bindings (cont.)
The selection selection get selection get FILE_NAME Issuing commands to other Tk applications send tgdb “break tkEval.c:200” winfo interps returns: wish tgdb ppres Window information winfo width .x winfo children .x winfo containing $x $y Other Tk Commands
Keyboard focus focus .x.y Communication with window manager wm title . “Editing main.c” wm geometry . 300x300 wm iconify . Deleting windows destroy .x Grabs grab .x grab release .x Access to Other Window Facilities
toplevel .d message .d.top -width 3i -bd 2 \ -relief raised -justify center -font \ *-helvetica-medium-r-normal--*-240-* \ -text “File main.c hasn’t been \ saved to disk since it was last \ modified. What should I do?” pack .d.top -side top -fill both Example 1: Dialog Box
frame .d.bot pack .d.bot -side bottom -fill both button .d.bot.left -text “Save File” \ -command “quit save” pack .d.bot.left -side left \ -expand yes -padx 20 -pady 20 button .d.bot.mid -text “Quit Anyway” \ -command “quit quit” pack .d.bot.mid -side left \ -expand yes -padx 20 -pady 20 Dialog Box Cont.
button .d.bot.right -text “Return to Editor” \ -command “quit return” pack .d.bot.right -side left \ -expand yes -padx 20 -pady 20 proc quit button { puts stdout “You pressed the \ $button button; bye-bye” destroy .d } Dialog Box Cont.
listbox .list -yscroll “.scroll set” \ -relief raised -width 20 -height 15 pack .list -side left scrollbar .scroll -command “.list yview” pack .scroll -side right -fill y Example 2: Browser
if {$argc > 0} { set dir [lindex $argv 0] } else {set dir .} foreach i [exec ls -a $dir] { .list insert end $i } Browser Cont.
bind .list <Double-Button-1> { browse $dir [selection get] bind .list <Control-c> {destroy .} focus .list proc browse {dir file} { if {$dir != “.”} { set file $dir/$file } if [file isdirectory $file] { exec browse $file & } else { if [file isfile $file] { exec $env(EDITOR) $file & } else { puts stdout “\”$file\” isn’t \ a regular file or directory” } } } Browser Cont.
Top-level canvas with x and y scrollbars 20x10 array of rectangles with (i,j) index label select and print rectangle labels pan canvas Example 3: Scrolling Canvas
Create top level widget Inform window manager of size, title, etc. proc mkScroll {{w .cscroll}} { catch {destroy $w} toplevel $w wm geometry $w +300+300 wm title $w "Scrollable Canvas Demonstration" wm iconname $w "Canvas" wm minsize $w 100 100 Example 3: Scrolling Canvas
Create header message and quit button message $w.msg \ -font -Adobe-Times-Medium-R-Normal-*-180-* \ -aspect 300 -relief raised -bd 2 -text {This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with button 2 in the canvas. If you click button 1 on one of the rectangles, its indices will be printed on stdout.} frame $w.frame -relief raised -bd 2 button $w.ok -text "OK" -command "destroy $w" pack $w.msg -side top -fill x pack $w.ok -side bottom -pady 5 pack $w.frame -side top -expand yes -fill both Scrolling Canvas Cont.
Create canvas and scrollbars fix maximum scrolling/drawing region set up link between scroll bars and canvas set c $w.frame.c canvas $c -scrollregion {-10c -10c 50c 20c} \ -xscroll "$w.frame.hscroll set" \ -yscroll "$w.frame.vscroll set" scrollbar $w.frame.vscroll -relief sunken \ -command "$c yview" scrollbar $w.frame.hscroll -orient horiz \ -relief sunken -command "$c xview" pack $w.frame.vscroll -side right -fill y pack $w.frame.hscroll -side bottom -fill x pack $c -expand yes -fill both Scrolling Canvas Cont.
Draw 20x10 array of rectangles and labels rectangles of background color outlined in black black text “i, j” centered in rectangle set bg [$c cget -bg] for {set i 0} {$i < 20} {incr i} { set x [expr {-10 + 3*$i}] for {set j 0; set y -10} {$j < 10} {incr j; incr y 3} { $c create rect ${x}c ${y}c [expr $x+2]c \ [expr $y+2]c -outline black -fill $bg -tags rect $c create text [expr $x+1]c [expr $y+1]c \ -text "$i,$j" -anchor center -tags text } } Scrolling Canvas Cont.
Bind canvas item events to mouse callback procedures highlight rectangle when mouse enters it unhighlight rectangle when mouse leaves print text label when button 1 clicked over rectangle Pan canvas when dragging with button 2 down $c bind all <Any-Enter> "scrollEnter $c" $c bind all <Any-Leave> "scrollLeave $c" $c bind all <1> "scrollButton $c" bind $c <2> "$c scan mark %x %y" bind $c <B2-Motion> "$c scan dragto %x %y" } # end of mkScroll Scrolling Canvas Cont.
Mouse event callback procedures scrollEnter - called when entering rectangle scrollLeave - called when leaving rectangle scrollButton - called when button click in rectangle proc scrollEnter canvas { global oldFill set id [$canvas find withtag current] if {[lsearch [$canvas gettags current] text] >= 0} { set id [expr $id-1] } set oldFill [$canvas itemcget $id -fill] if {[tk colormodel $canvas] == "color"} { $canvas itemconfigure $id -fill SeaGreen1 } else { $canvas itemconfigure $id -fill black $canvas itemconfigure [expr $id+1] -fill white } } Scrolling Canvas Cont.
proc scrollLeave canvas { global oldFill set id [$canvas find withtag current] if {[lsearch [$canvas gettags current] text] >= 0} { set id [expr $id-1] } $canvas itemconfigure $id -fill $oldFill $canvas itemconfigure [expr $id+1] -fill black } proc scrollButton canvas { global oldFill set id [$canvas find withtag current] if {[lsearch [$canvas gettags current] text] < 0} { set id [expr $id+1] } puts stdout "You buttoned at \ [lindex [$canvas itemconf $id -text] 4]" } mkScroll Scrolling Canvas Cont.
Creating interfaces with Tcl scripts is easy create widgets arrange with geometry managers connect to application, each other Power from single scripting language for specifying user interface for widgets to invoke application for widgets to communicate with each other for communicating with outside world for changing anything dynamically Summary