Forum: Ruby A Tk window

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2009-02-03 09:59
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...
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-02-03 14:27
(Received via mailing list)
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!
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-02-04 07:58
(Received via mailing list)
> 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.!!
990bf71a4e84e1145a3131f35656dc18?d=identicon&s=25 List Rb (listx300108u79872)
on 2009-02-04 08:17
(Received via mailing list)
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 ;-)
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2009-02-04 08:57
(Received via mailing list)
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
}
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2009-02-04 14:40
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.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-02-04 16:35
(Received via mailing list)
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!
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2009-02-05 03:37
(Received via mailing list)
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.
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2009-02-05 12:26
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?
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2009-02-05 12:54
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/install.html

(Why do I get the impression that "The Tk Way" equals "Nothing works out
of the box"?)
7ece60b3b5bb235d1b6df89727ca6cf7?d=identicon&s=25 mdiam (Guest)
on 2009-02-05 14:20
(Received via mailing list)
On Feb 5, 12:53 pm, Albert Schlef <albertsch...@gmail.com> wrote:

> (Why do I get the impression that "The Tk Way" equals "Nothing works out
> of the box"?)

It's not true for Tk but I agree the **Ruby/Tk** is difficult to make
working
only because Tk is not part of Ruby.


-- Maurice
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2009-02-05 14:55
Albert Schlef wrote:
>> What does this entail? Will I have to compile Tcl/Tk/Ruby myself?
>
> Nevermind, I've found instructions, here:
>
> http://www.tkdocs.com/tutorial/install.html

I gave up, it's too complicated for me. I'll just wait for the next
release of Ubuntu.


mdiam wrote:
> Albert Schlef wrote:
>> (Why do I get the impression that "The Tk Way" equals "Nothing works out
>> of the box"?)
>
> It's not true for Tk but I agree the **Ruby/Tk** is difficult to make
> working only because Tk is not part of Ruby.

It isn't? Well. Actually, if it was shipped as a gem we could just do
"gem update tk" and it'd work with the newest Tk, wouldn't it?
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-02-05 18:51
(Received via mailing list)
mdiam wrote:

> It's not true for Tk but I agree the **Ruby/Tk** is difficult to make
> working
> only because Tk is not part of Ruby.

I can't remember the last time I built a ruby.*tar.gz tarball and did
not get a
Ruby/Tk...
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2009-02-05 21:09
(Received via mailing list)
From: Albert Schlef <albertschlef@gmail.com>
Subject: Re: A Tk window
Date: Thu, 5 Feb 2009 22:55:04 +0900
Message-ID: <584be7f2ea0b447f512b957e71a96d83@ruby-forum.com>
> >> What does this entail? Will I have to compile Tcl/Tk/Ruby myself?
> >
> > Nevermind, I've found instructions, here:
> >
> > http://www.tkdocs.com/tutorial/install.html
>
> I gave up, it's too complicated for me. I'll just wait for the next
> release of Ubuntu.

Did you see '<ruby-src-tree>/ext/tk/README.tcltklib' ?
Can't it help you ?
11b74267d849cc2c95e66c634c1b53f9?d=identicon&s=25 Mark Roseman (Guest)
on 2009-02-06 19:35
(Received via mailing list)
As the author of the www.tkdocs.com site, I'd very much welcome any
feedback as to the installation instructions, and particularly if anyone
knows easier ways to get things running!
Mark
7ece60b3b5bb235d1b6df89727ca6cf7?d=identicon&s=25 mdiam (Guest)
on 2009-02-07 17:09
(Received via mailing list)
> >> ...that "The Tk Way" equals "Nothing works out
> >> of the box"?)
>
> mdiam said:
> > ... the **Ruby/Tk** is difficult to make working
> > only because Tk is not part of Ruby.
>
> It isn't? Well. Actually, if it was shipped as a
> gem we could just do "gem update tk" and it'd work
> with the newest Tk, wouldn't it?

I agree that a "gem upgrade tk" would be nice, but
I'm not sure it's feasable while Tk is not part
of Ruby?
-- Maurice
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2009-02-08 00:48
Hidetoshi NAGAI wrote:
> From: Albert Schlef <albertschlef@gmail.com>
>> > Nevermind, I've found instructions, here:
>> >
>> > http://www.tkdocs.com/tutorial/install.html
>>
>> I gave up, it's too complicated for me. I'll just wait for the next
>> release of Ubuntu.
>
> Did you see '<ruby-src-tree>/ext/tk/README.tcltklib' ?
> Can't it help you ?

Thanks! I made it. It was actually simple. My Tk apps look decent now
:-)

Mark Roseman wrote:
> As the author of the www.tkdocs.com site, I'd very much
> welcome any feedback as to the installation instructions

Two things:

1. There's no need to compile the whole Ruby. After I extracted Ruby's
source tarball I went to the 'ext/tk' folder and compiled only the Tk
extension. As Nagai points out, that folder has a README.tcltklib which
lists the command line options one needs to pass to 'ruby extconf.rb'.

2. There's no need to mention ActiveState or ActiveTcl. On my linux
distro (Ubuntu) I just type "sudo apt-get install tcl8.5 tcl8.5-dev
tk8.5 tk8.5-dev" and everything gets installed.
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2009-02-08 21:45
(Received via mailing list)
Hidetoshi NAGAI wrote:
>
> Did you see '<ruby-src-tree>/ext/tk/README.tcltklib' ?
> Can't it help you ?

I haven't gotten ruby/tk to work with 8.5. It's been ok with 8.4 but
segfaults with 8.5.

This is on ubuntu. I build tcl8.5.6 and tk8.5.6 with

./configure --disable-threads --prefix=/usr/local
make && make install

The tk demos run correctly.

Then I build ruby (1.8.6-p287) with:

./configure --disable-pthread --with-tcl-dir=/usr/local
--with-tk-dir=/usr/local --disable-tcl-thread
make && make install

(I tried just rebuilding ext/tk as described in README.tcltklib, but the
effect was the same.)

Then *some* of the ruby/tk demos run but some segfault. For example:

$ ruby 24hr_clock.rb
*** glibc detected *** ruby: free(): invalid next size (fast):
0x08448d78 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7dbca85]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7dc04f0]
/usr/local/lib/libtcl8.5.so(TclpFree+0x1d)[0xb7a0ee8d]
/usr/local/lib/libtcl8.5.so(Tcl_Free+0x1d)[0xb7a1872d]
/usr/local/lib/libtcl8.5.so[0xb7aa4550]
/usr/local/lib/libtcl8.5.so[0xb7a161ca]
/usr/local/lib/libtcl8.5.so(Tcl_GetByteArrayFromObj+0x3b)[0xb7a1623b]
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/tcltklib.so[0xb7bfe1ae]
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/tcltklib.so[0xb7bfedf5]
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/tcltklib.so[0xb7bff2dd]
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/tcltklib.so[0xb7bffb65]
/usr/local/lib/ruby/site_ruby/1.8/i686-linux/tcltklib.so[0xb7bffdce]

(and more backtrace and dump data)

Any ideas?
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2009-02-09 07:43
(Received via mailing list)
From: Albert Schlef <albertschlef@gmail.com>
Subject: Re: A Tk window
Date: Sun, 8 Feb 2009 08:48:04 +0900
Message-ID: <111f9e97d74ee56387b89d73a5fe6cc4@ruby-forum.com>
> 2. There's no need to mention ActiveState or ActiveTcl. On my linux
> distro (Ubuntu) I just type "sudo apt-get install tcl8.5 tcl8.5-dev
> tk8.5 tk8.5-dev" and everything gets installed.

Except useful Tcl/Tk extensions.
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2009-02-09 07:44
(Received via mailing list)
From: Joel VanderWerf <vjoel@path.berkeley.edu>
Subject: Re: A Tk window
Date: Mon, 9 Feb 2009 05:43:28 +0900
Message-ID: <498F4419.5080507@path.berkeley.edu>
> Then I build ruby (1.8.6-p287) with:
>
> ./configure --disable-pthread --with-tcl-dir=/usr/local
> --with-tk-dir=/usr/local --disable-tcl-thread
> make && make install
>
> (I tried just rebuilding ext/tk as described in README.tcltklib, but the
> effect was the same.)
>
> Then *some* of the ruby/tk demos run but some segfault. For example:

Probably, your Tcl/Tk libraries are compiled with threads support
option.
The following table is the relation of thread support between
Ruby and Tcl/Tk.

                   |  Tcl/Tk with threads  |   without threads
-------------------+-----------------------+------------------------
 Ruby with pthread |         work          |    possibly work
-------------------+-----------------------+------------------------
  without pthread  | NOT work (freq. SEGV) |         work
-------------------+-----------------------+------------------------

"--disable-tcl-thread" option doesn't change thread support status of
Tcl/Tk libraries.
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2009-02-09 19:37
(Received via mailing list)
Hidetoshi NAGAI wrote:
>> make && make install
>> effect was the same.)
> -------------------+-----------------------+------------------------
>   without pthread  | NOT work (freq. SEGV) |         work
> -------------------+-----------------------+------------------------
>
> "--disable-tcl-thread" option doesn't change thread support status of
> Tcl/Tk libraries.

You're right about my tk lib using pthread, but I'm not sure why:

$ ldd libtk8.5.so | grep thread
         libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0
(0xb7b2d000)

But I did rebuild tcl and tk with the options shown above, including
--disable-threads. The strange thing is that this worked for me in the
past with 8.4. Is there some other option that I have to pass to
configure to disable pthread?

Interestingly,

$ ldd libtcl8.5.so | grep thread

has empty output. So somehow tk is building with pthread, but tcl is
not. I used the same configure arguments for both.

I just rebuilt tk8.5.6 again with

./configure --disable-threads --prefix=/usr/local

and the still the resulting libtk8.5.so depends on libpthread.
This topic is locked and can not be replied to.