Feedback messages to user using Tk

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!

Gem

···

-----Original Message-----
From: Morton Goldberg [mailto:m_goldberg@ameritech.net]
Sent: 27 September 2006 15:22
To: ruby-talk ML
Subject: Re: Feedback messages to user using Tk...

               *** WARNING ***

This mail has originated outside your organization, either from an
external partner or the Global Internet.
     Keep this in mind if you answer this message.

On Sep 27, 2006, at 9:28 AM, Cameron, Gemma (UK) wrote:

Thanks a lot Morton, I'll have a look at this widget when I get home (

:

I had tried something similar to what you suggested with a method, but

there was no way of triggering it - i think i needed to perhaps run it

as a seperate process...

I hope not. That will complicate things quite a bit. Before you do that
I would suggest trying the following:

1. Expose the label by supplying and attribute reader for it in the
window class OR provide a public method in the window to update the
label (like btn_action but accepting a string argument).
2. Provide your file zipper class with code that either directly updates
the label or calls the update method in the window class.
3. Don't call Tk.mainloop in your window class.
4. Create the window object.
5. Create the file zipper object, passing the window object in 'new'.
6. Now call Tk.mainloop

Regards, Morton

********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

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.

<code>
#! /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
</code>

Regards, Morton

···

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!