Morton Goldberg
4/23/2007 2:49:00 AM
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
<code>
#! /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
</code>