Basic RubyTk questions

I have a Mac OS X system. I wrote a Ruby program that uses RubyTk to
display a TkLabel. It works, but I'd like a bit more control over how
it looks. Here's the code minus the non-Tk stuff that isn't relevant
to my questions:

require 'tk'

answer = 'test'
TkLabel.new do
  text answer
  foreground 'yellow'
  background 'black'
  # place('x' => 400, 'y' = 400)
  pack('padx' => 15, 'pady' => 15)
end

def timer_loop3
  exit
end
TkAfter.new(3000, # milliseconds
            -1, # ?
            proc{timer_loop3} # what to call when the timer expires
).start

Tk.mainloop

The program displays a label for 3 seconds and exits, as intended,
but...

1. How do I control the placement of the label on the screen? It now
apppears
   near the upper left-hand corner. I tried "place" (commented out)
with no
   luck.
2. How can I make the label appear on top of other windows? It naw
appears
   "under" other windows, so I only see the label if I keep the
upper-left part
   of my screen free of other windows.
3. Is there a way to remove the borders? I don't need the title bar.
4. I use this as a Mac OS X service, dufined with ThisService, a great
little
   program. When I run it as a service, two windows appear. One is
titled "tk"
   and the other is the same as what I see when I run the program from
the
   command line. Can I get rid of the "tk" window?
5. Of course, is there a better way to do this?

-- Pete

···

--
Posted via http://www.ruby-forum.com/.

I have a Mac OS X system. I wrote a Ruby program that uses RubyTk to
display a TkLabel. It works, but I'd like a bit more control over how
it looks. Here's the code minus the non-Tk stuff that isn't relevant
to my questions:

require 'tk'

answer = 'test'
TkLabel.new do
  text answer
  foreground 'yellow'
  background 'black'
  # place('x' => 400, 'y' = 400)
  pack('padx' => 15, 'pady' => 15)
end

def timer_loop3
  exit
end
TkAfter.new(3000, # milliseconds
            -1, # ?

The -1 requests an indefinite number of timeout events. Since you are going to exit on the first timeout, I suggest using 1 here, but it doesn't really matter.

            proc{timer_loop3} # what to call when the timer expires
).start

Tk.mainloop

The program displays a label for 3 seconds and exits, as intended,
but...

1. How do I control the placement of the label on the screen? It now apppears
   near the upper left-hand corner. I tried "place" (commented out) with no
   luck.

The 'place' method affects the geometry of a widget within its container. It does not affect the placement of the window containing the widget on the screen.

2. How can I make the label appear on top of other windows? It now appears
   "under" other windows, so I only see the label if I keep the upper-left part
   of my screen free of other windows.

The following ought to fix it, but it doesn't.

    root.focusmodel(:active)
    root.focus(true)

This appears to be a problem with Tk. I don't know a work-around.

3. Is there a way to remove the borders? I don't need the title bar.

The borders, yes. The title bar I don't know how to remove.

4. I use this as a Mac OS X service, defined with ThisService, a great little
   program. When I run it as a service, two windows appear. One is titled "tk"
   and the other is the same as what I see when I run the program from the
   command line. Can I get rid of the "tk" window?

If you watch carefully, sometimes you will see this window appear momentarily even when you run from the command line. I don't know why it persists when you run your script as a service.

5. Of course, is there a better way to do this?

There's always a better way to do something with Ruby :slight_smile: The following is the best I can do with Ruby/Tk. I don't know if you will think it's good enough, but it solves some of your problems.

<code>
#! /usr/bin/ruby -w
require 'tk'

SEC = 3 # display duration in seconds

TkLabel.new do
    text 'Hello, World!'
    font "HelveticaBold 36"
    foreground 'yellow'
    background 'black'
    pack(:fill => :both, :expand => true)
end

root = Tk.root
root.title('') # suppress title (title bar remains)
# Set initial window geometry; i.e., size and placement
win_y, win_w, win_h = 50, 300, 80
win_x = (root.winfo_screenwidth - win_w) / 2 # center on screen
root.geometry("#{win_w}x#{win_h}+#{win_x}+#{win_y}")
# Suppress resizing window
root.resizable(false, false)

# One-shot timer
TkTimer.new(SEC * 1000, 1) { root.destroy }.start

Tk.mainloop
</code>

This may be a situation where Ruby/Tk just won't cut it. The better way you are looking for may require using a GUI library other than Ruby/Tk.

Regards, Morton

···

On Aug 17, 2007, at 11:45 AM, Pete Siemsen wrote:

You are not very clear of what exaclty you intend to do, place what,
where?, but I think Morton's example can help you alot. Anyway if your
target is only MacOS X try RubyCocoa
(http://blog.8thlight.com/articles/2007/08/13/rubycocoa-tutorial). I
think you can use the XCode interface builder in that case.
Regards.

···

--
Posted via http://www.ruby-forum.com/.

I have a Mac OS X system. I wrote a Ruby program that uses RubyTk to
display a TkLabel. It works, but I'd like a bit more control over how
it looks. Here's the code minus the non-Tk stuff that isn't relevant
to my questions:

<snip>

5. Of course, is there a better way to do this?

Now that _has_ has set me straight on how to use the osax library, I can suggest another idea:

<code>
#! /usr/bin/env ruby
require "osax"

SEC = 3 # display duration

std_adds = OSAX::osax(nil, "System Events")
std_adds.display_alert("This is a test",
    :message => "This is only a test",
    :giving_up_after => SEC,
    :as => :warning)
</code>

Using OSA scripting additions has two virtues:

1. Much simpler to use than Ruby/Tk (once you know what library to require :).
2. As far as I can tell, the alert will always pop-up on top of any other window that might be present on the screen.

If all you want to do is pop-up an short message every now and then, this may work for you.

Regards, Morton

···

On Aug 17, 2007, at 11:45 AM, Pete Siemsen wrote: