From: Morton Goldberg Date: 2007-04-23T11:49:28+09:00 Subject: Re: refreshing a ruby tk window/scrollbox On Apr 22, 2007, at 6:51 PM, DBH wrote: > I have a TkScrollBox object that displays a list of records. I > want to > sort the list and filter it in various ways, but the only way I've > figured out how to do this is to get rid of the old window and > create a > new window with the sorting option. My question is, is there a way to > refresh a TkScrollBox or the window itself so I don't have to create a > new window each time? What I do in situations similar to what you describe is to delete the contents of the list box and repopulate it with new contents. The following is a rather long example demonstrating this technique. I'm sorry I don't have a shorter one. The technique is coded into X11ColorBrowser#category_selected_action. Hope this helps. Regards, Morton #! /usr/bin/ruby -w # Author: Morton Goldberg # Date: August 26, 2006 # X11 color browser require 'tk' class X11ColorCategory # Full path name of the X11 colors file. RGB_TXT = "/usr/X11R6/lib/X11/rgb.txt" #Dictionary of rgb values keyed by color name. COLORS = {} def X11ColorCategory.read_rgb_table # read and parse the X11 colors file. File.foreach(RGB_TXT) do |rgb| next if rgb =~ /^!/ # skip header line rgb = rgb.lstrip.split(/\s+/) r = rgb.shift g = rgb.shift b = rgb.shift key = rgb.join(' ') COLORS[key] = "r:#{r} g:#{g} b:#{b}" end COLORS end def X11ColorCategory.all ALL_CATEGORIES end def X11ColorCategory.rgb(color_name) COLORS[color_name] end def extract(pattern) @members, OTHER.members = OTHER.members.partition { |m| m =~ pattern } self end def initialize(name) @name = name @members = [] end attr_accessor :name, :members ALL = X11ColorCategory.new('ALL') X11ColorCategory.read_rgb_table.each {|key,| ALL.members << key} ALL.members.sort! OTHER = X11ColorCategory.new('OTHER') ALL.members.each {|m| OTHER.members << m} REDS = X11ColorCategory.new('REDS'). extract(/red|rose|pink|salmon|fire/i) GREENS = X11ColorCategory.new('GREENS'). extract(/green|chartreuse|olive|honeydew/i) BLUES = X11ColorCategory.new('BLUES'). extract(/blue|navy/i) CYANS = X11ColorCategory.new('CYANS'). extract(/cyan|aqua|azure|turquoise/i) MAGENTAS = X11ColorCategory.new('MAGENTAS'). extract(/magenta|maroon|violet|plum|purple|orchid|thistle/i) YELLOWS = X11ColorCategory.new('YELLOWS'). extract(/yellow|gold|lemon|corn/i) ORANGES = X11ColorCategory.new('ORANGES'). extract(/orange|tomato|peach|coral/i) BROWNS = X11ColorCategory.new('BROWNS'). extract(/brown|tan|wood|choc|sienna|wheat|peru/i) WHITES = X11ColorCategory.new('WHITES'). extract(/white|ivory|snow|lace/i) GRAYS = X11ColorCategory.new('GRAYS'). extract(/gr[ae]y|gainsboro/i) ALL_CATEGORIES = [ REDS, ORANGES, YELLOWS, GREENS, CYANS, BLUES, MAGENTAS, BROWNS, WHITES, GRAYS, OTHER ] end class X11ColorBrowser # Action performed when category selection is made. def category_selected_action @category_names.focus @selected_category = X11ColorCategory.all[@category_names.curselection[0]] @color_names.delete(0, 'end') @selected_category.members.each { |m| @color_names.insert ("end", m) } @color_names.selection_set(0) color_selected_action end # Action performed when color selection is made. def color_selected_action color = @selected_category.members[@color_names.curselection[0]] @color_rect.background(color) @rgb_lbl.text(X11ColorCategory.rgb(color)) end # Action performed when browser window is mapped. def window_mapped_action return if @mapped @mapped = true X11ColorCategory.all.each do |category| @category_names.insert("end", category.name) end @category_names.selection_set(0) category_selected_action end def initialize # Flag indicating that window has been mapped at least once. @mapped = false # Holder for currently selected color category @selected_category = nil # Set up the browser window. root = TkRoot.new {title 'Color Browser'} # Panel at top of browser containing scrolling list of X11 colors and # label displaying selected color. top_pnl = TkFrame.new(root) # List box displaying names of X11 color categories. @category_names = TkListbox.new(top_pnl) # Scroll bar for the color names list. vbar1 = TkScrollbar.new(top_pnl) @category_names.yscrollbar(vbar1) # List box displaying names of X11 colors within selected category. @color_names = TkListbox.new(top_pnl) # Scroll bar for the color names list. vbar2 = TkScrollbar.new(top_pnl) @color_names.yscrollbar(vbar2) # Label displaying selected color. @color_rect = TkLabel.new(top_pnl, 'width'=>25) # Request layout of top panel. @category_names.pack("side"=>"left", "fill"=>"both", "expand"=>true, "padx"=>5) vbar1.pack("side"=>"left", "after"=>@category_names, "fill"=>"y") @color_names.pack("side"=>"left", "after"=>vbar1, "fill"=>"both", "expand"=>true, "padx"=>5) vbar2.pack("side"=>"left", "after"=>@color_names, "fill"=>"y") @color_rect.pack("side"=>"right", "fill"=>"both", "expand"=>true, "padx"=>5) top_pnl.pack("side"=>"top", "fill"=>"both", "expand"=>true, "padx"=>5, "pady"=>8) # Panel at bottom of browser containing exit button and label # displaying RGB values of selected color. btm_pnl = TkFrame.new(root) # Label displaying rgb values of selected color. @rgb_lbl = TkLabel.new(btm_pnl) { text "r:xxx g:xxx b:xxx" } # Exit button. @quit_btn = TkButton.new(btm_pnl) { text "Exit" command { Tk.root.destroy } } # Request layout of bottom panel. @rgb_lbl.pack("side"=>"left", "anchor"=>"w") @quit_btn.pack("side"=>"right") btm_pnl.pack("side"=>"bottom", "fill"=>"x", "padx"=>10, "pady"=>8) # Set initial window geometry; i.e., size and placement. win_w, win_h = 750, 300 root.minsize(win_w, win_h) win_x = (root.winfo_screenwidth - win_w) / 2 root.geometry("#{win_w}x#{win_h}+#{win_x}+50") # Make Cmnd+Q work as expected (for Mac OS X). root.bind('Command-q') { @quit_btn.invoke } # Bind mouse button-1, space bar, window map event to their actions. @category_names.bind('Map') { window_mapped_action } ev = TkVirtualEvent.new('ButtonRelease-1', 'space') @category_names.bind(ev) { category_selected_action } @color_names.bind(ev) { color_selected_action } Tk.mainloop end end X11ColorBrowser.new