From: Morton Goldberg Date: 2006-09-28T02:18:11+09:00 Subject: Re: Feedback messages to user using Tk... On Sep 27, 2006, at 10:57 AM, Cameron, Gemma (UK) wrote: > 6. Now call Tk.mainloop > > ^^ I think maybe that's where I was going wrong. I wrote a unit > test to > test the updating of the label. My code looked something like this: > > class GraphicalProgress > def initialize > root = TkRoot.new { title 'Progress' } > @my_label = tkLabel.new(root) > @my_label.configure('text'=>'Waiting for something to report...') > @my_label.pack > > Tk.mainloop > end > > def update(message) > @my_label.configure('text'=>'Waiting for something to report...') > end > end > > Unit Test: > > @progress = GraphicalProgress.new > @progress.update('I'm doing something') > @progress.update('I'm done') > > And because the loop is in the initialize method, only when the app is > closed do we get to the line which requests the text is update. Of > course this falls over as the widget has been destroyed... > > So with your suggestion the code should be something like this... > > class GraphicalProgress > def initialize > root = TkRoot.new { title 'Progress' } > @my_label = tkLabel.new(root) > @my_label.configure('text'=>'Waiting for something to report...') > @my_label.pack > end > > def update(message) > @my_label.configure('text'=>'Waiting for something to report...') > end > end > > Unit Test: > > @progress = GraphicalProgress.new > @progress.update('I'm doing something') > @progress.update('I'm done') > Tk.mainloop > > Or have I got the wrong end of the stick? > > Thanks so much for your help! There are quite a few errors in that code. Even if you fixed its syntax, you'd have a conceptual error. You'd only see the last message: "I'm done". The initial message would be replaced by the first update call and the second message would then be replaced by the second update call before the window got on the screen. But you're moving in the right direction. You need something to delay the updates until the window gets displayed. A timer is one way to do it. #! /usr/bin/ruby -w require 'tk' class GraphicalProgress def initialize root = TkRoot.new { title 'Progress' } @my_label = TkLabel.new(root) { text 'Waiting for something to report...' } @my_label.pack(:pady=>20) # Set initial window geometry; i.e., size and placement. win_w, win_h = 300, 80 # root.minsize(win_w, win_h) win_x = (root.winfo_screenwidth - win_w) / 2 root.geometry("#{win_w}x#{win_h}+#{win_x}+50") root.resizable(false, false) end def update(message) @my_label.text = message end end msgs = ["I'm doing something", "I'm done"] indx = 0 progress = GraphicalProgress.new timer = TkTimer.start(1000, 2) do progress.update(msgs[indx]) indx += 1 end Tk.mainloop Regards, Morton