[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

A Tk window

Albert Schlef

2/3/2009 9:00:00 AM

I have a program that run in the terminal. But once in a while I need it
to bring up a window (GUI) with some information (and interactive
widgets).

So I do:

root = TkRoot.new
.....set up the window.....
Tk.mainloop

This works. Then the user closes the window and the program continues
running.

HOWEVER, the next time I try to bring up the window, Tk gives the
following error:

can't invoke "frame" command: application has been destroyed
(RuntimeError)

(I also tried with TkToplevel instead of TkRoot.)

How can I solve this problem?

I looked into the source code of '/ext/tk/lib/dialog.rb', thinking
perhaps TkDialog is what I need. I tried the following code:

class MyDialog < TkDialog
def initialize(*args)
super(*args)
TkLabel.new(self, :text => 'this is a test').pack
end
end

MyDialog.new :title => 'something'

Now, this is already an improvement because I can call MyDialog.new()
again and again without Tk telling me that the "application has been
destroyed". HOWEVER, I can't put my own widgets in the dialog: my 'this
is a test' label doesn't show up...
--
Posted via http://www.ruby-....

21 Answers

Phlip

2/3/2009 1:24:00 PM

0

Albert Schlef wrote:

> root = TkRoot.new
> .....set up the window.....
> Tk.mainloop

> HOWEVER, the next time I try to bring up the window, Tk gives the
> following error:
>
> can't invoke "frame" command: application has been destroyed
> (RuntimeError)


Now here's a blast from the past:

def maybeMainloop(reveal = false)
if reveal then
Tk.mainloop()
Tk.restart()
@canvas = nil
end
end

Notice I was using 4-space indentations back then! Always remember that
following community standards, such as Ruby's Official 2-space indentations, is
much MUCH more important than producing lots of boring original research!

--
Phlip

aldric[removeme]

2/3/2009 1:28:00 PM

0

Albert Schlef wrote:
> I have a program that run in the terminal. But once in a while I need it
> to bring up a window (GUI) with some information (and interactive
> widgets).
>
> So I do:
>
> root = TkRoot.new
> .....set up the window.....
> Tk.mainloop
>
> This works. Then the user closes the window and the program continues
> running.
>
> HOWEVER, the next time I try to bring up the window, Tk gives the
> following error:
>
> can't invoke "frame" command: application has been destroyed
> (RuntimeError)
>
> (I also tried with TkToplevel instead of TkRoot.)
>
> How can I solve this problem?
>
> I looked into the source code of '/ext/tk/lib/dialog.rb', thinking
> perhaps TkDialog is what I need. I tried the following code:
>
> class MyDialog < TkDialog
> def initialize(*args)
> super(*args)
> TkLabel.new(self, :text => 'this is a test').pack
> end
> end
>
> MyDialog.new :title => 'something'
>
> Now, this is already an improvement because I can call MyDialog.new()
> again and again without Tk telling me that the "application has been
> destroyed". HOWEVER, I can't put my own widgets in the dialog: my 'this
> is a test' label doesn't show up...
>
Cheat, override the 'close' button and make it hide the window instead?

Phlip

2/3/2009 1:51:00 PM

0

> Cheat, override the 'close' button and make it hide the window instead?

Then the Tk.mainloop keeps ticking, meaning you have to then slice up your outer
algorithm and put it in a timer, etc. etc.!!

Hidetoshi NAGAI

2/4/2009 3:43:00 AM

0

From: Phlip <phlip2005@gmail.com>
Subject: Re: A Tk window
Date: Tue, 3 Feb 2009 22:54:48 +0900
Message-ID: <kZXhl.11748$W06.4001@flpi148.ffdc.sbc.com>

> > Cheat, override the 'close' button and make it hide the window instead?

Tk.root.protocol('WM_DELETE_WINDOW'){Tk.root.withdraw}

> Then the Tk.mainloop keeps ticking, meaning you have to then slice up your outer
> algorithm and put it in a timer, etc. etc.!!

There is a trick ;-)
-----------------------------------------------------------
require 'tk'

class MyWin
def initialize
@v = TkVariable.new
r = Tk.root
r.protocol('WM_DELETE_WINDOW'){r.withdraw; Tk.update; @v.value = 1}
TkButton.new(:text=>'TEST', :command=>proc{puts 'running!'}).pack
end

def start_eventloop
Tk.root.deiconify
@v.wait # wait command makes a eventloop while waiting
end
end

w = MyWin.new
5.times{
w.start_eventloop
p Thread.list
sleep 3
}
-----------------------------------------------------------
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)

list. rb

2/4/2009 6:16:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

On Tue, Feb 3, 2009 at 8:54 AM, Phlip <phlip2005@gmail.com> wrote:

> Cheat, override the 'close' button and make it hide the window instead?
>>
>
> Then the Tk.mainloop keeps ticking, meaning you have to then slice up your
> outer algorithm and put it in a timer, etc. etc.!!
>
>
+1 for larger indentations ;-)

Albert Schlef

2/4/2009 1:40:00 PM

0

Phlip wrote:
[...]
> Now here's a blast from the past:
[...]
> Tk.mainloop()
> Tk.restart()

Superb! That solved my problem. Thanks.

(BTW, suppose I'll be running my code inside a Tk application. In that
case I wouldn't want to execute Tk.mainloop() (and restart(), of course)
at all. Any way to find out if we're already running in a Tk
application?)

>
> Notice I was using 4-space indentations [...]

LOL

Hidetoshi NAGAI wrote:
> There is a trick ;-)
[...]
> @v.wait # wait command makes a eventloop while waiting

Thanks, Nagai, but this is too much voodoo for me :-) I don't bother to
study the "dark" corners of Tk because I have a feeling Tk is a
dead-end. (It has an ingeniously simple API, I admit, but the facts that
I struggled yesterday to fetch the selcted item from a TkListbox, and
even more to add scrollbars, and that the fonts are so ugly and
unreadable, show that Tk has been dormant for at least 15 years.) But it
seems we don't have much choice. GTK requires you to memorize CONSTANTS.
Shoes doesn't have mature widgets. FOX is a pain to compile. So we go
with Tk.
--
Posted via http://www.ruby-....

Phlip

2/4/2009 3:31:00 PM

0

Albert Schlef wrote:

>> Tk.mainloop()
>> Tk.restart()
>
> Superb! That solved my problem. Thanks.

Read and obey the post by Hidetoshi NAGAI. He maintains RubyTk, AFAIK!

> (BTW, suppose I'll be running my code inside a Tk application. In that
> case I wouldn't want to execute Tk.mainloop() (and restart(), of course)
> at all. Any way to find out if we're already running in a Tk
> application?)

If a GUI is already running, then if you block its main loop, the user will see
the window lock up. So use @v.wait...

> GTK requires you to memorize CONSTANTS.
> Shoes doesn't have mature widgets. FOX is a pain to compile. So we go
> with Tk.

Yay!

Hidetoshi NAGAI

2/5/2009 2:37:00 AM

0

From: Albert Schlef <albertschlef@gmail.com>
Subject: Re: A Tk window
Date: Wed, 4 Feb 2009 22:40:16 +0900
Message-ID: <8e4169fd337e5c6f2f00f947a74c508b@ruby-forum.com>
> dead-end. (It has an ingeniously simple API, I admit, but the facts that
> I struggled yesterday to fetch the selcted item from a TkListbox, and
> even more to add scrollbars,

Hmm... I think that it not so difficult.
Possibly, Ruby/Tk is easier than Tcl/Tk.
-------------------------------------------------------------------
require 'tk'

f = TkFrame.new.pack(:expand=>true, :fill=>:both)

lbox = TkListbox.new(f)
lbox.yscrollbar(TkScrollbar.new(f).pack(:side=>:right, :fill=>:y))
lbox.pack(:side=>:right, :expand=>true, :fill=>:both)
lbox.bind('<ListboxSelect>', :widget){|w|
# :widget equal to "%W" (see Tcl/Tk's "bind" manual).
# current Ruby/Tk supports accessor-names of Tk::Event object instead of
# "%" substitutions.
p [w.curselection, w.get(w.curselection[0])]
}

lbox.value = %w(a b c foo bar baz hoge fuga zzz asdf qwer zxcv)
lbox.focus

Tk.mainloop
-------------------------------------------------------------------

> and that the fonts are so ugly and
> unreadable, show that Tk has been dormant for at least 15 years.)

Well, I recommend you to use Tcl/Tk8.5 for your Ruby/Tk.
Tcl/Tk8.5 supports anti-aliased fonts on X window systems,
and includes Tile (Ttk) extension (widget styling engine) as default.
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)

Albert Schlef

2/5/2009 11:26:00 AM

0

Hidetoshi NAGAI wrote:
> From: Albert Schlef <albertschlef@gmail.com>
> > and that the fonts are so ugly and
> > unreadable, show that Tk has been dormant for at least 15 years.)
>
> Well, I recommend you to use Tcl/Tk8.5 for your Ruby/Tk.
> Tcl/Tk8.5 supports anti-aliased fonts on X window systems,

What does this entail? Will I have to compile Tcl/Tk/Ruby myself?
--
Posted via http://www.ruby-....

Albert Schlef

2/5/2009 11:54:00 AM

0

Albert Schlef wrote:
> Hidetoshi NAGAI wrote:
>> Well, I recommend you to use Tcl/Tk8.5 for your Ruby/Tk.
>> Tcl/Tk8.5 supports anti-aliased fonts on X window systems,
>
> What does this entail? Will I have to compile Tcl/Tk/Ruby myself?

Nevermind, I've found instructions, here:

http://www.tkdocs.com/tutorial/in...

(Why do I get the impression that "The Tk Way" equals "Nothing works out
of the box"?)
--
Posted via http://www.ruby-....