Forum: Ruby Tk TopLevel 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.
5f42414a1b1b2cdf419fc36e6127fe70?d=identicon&s=25 Jason (Guest)
on 2007-06-30 16:58
I have been searching for awhile but cannot find the answer to my
question.
I have a TkRoot window that when a button is clicked, a new TkToplevel
window is created.

I don't want the user to be able to get focus of the TkRoot window until
the TkToplevel window is closed. Much like a dialog box. I could
probably catch the FocusOut event on the TkToplevel window and grab
focus again but that seems like a hacked way to do it. Is there an
easier way?
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2007-07-02 04:06
(Received via mailing list)
From: Jason <jasonlfunk@gmail.com>
Subject: Tk TopLevel window
Date: Sat, 30 Jun 2007 23:58:33 +0900
Message-ID: <e4ece3bb25ff08e4bed0dc6772a4b48b@ruby-forum.com>
> I have a TkRoot window that when a button is clicked, a new TkToplevel
> window is created.
>
> I don't want the user to be able to get focus of the TkRoot window until
> the TkToplevel window is closed. Much like a dialog box. I could
> probably catch the FocusOut event on the TkToplevel window and grab
> focus again but that seems like a hacked way to do it. Is there an
> easier way?

Please use TkWindow#set_grab/release_grab methods,
and some kinds of tkwait methods.

# See also Tcl/Tk's manuals about 'tkwait' and 'vwait'.

For example,
---------------------------------------------------------------
require 'tk'

def create_onetime_toplevel(btn)
  top = TkToplevel.new(btn).withdraw
  TkLabel.new(top, :text=>'self.object_id == ' <<
top.object_id.to_s).pack
  e = TkEntry.new(top).pack
  TkButton.new(top, :text=>'CLOSE', :command=>proc{top.destroy}).pack
  top.deiconify
  e.focus
  top.set_grab
  top.wait_destroy  # same as top.tkwait_destroy
  top.release_grab
end

def create_reusable_toplevel(btn, var)
  top = TkToplevel.new(btn).withdraw
  TkLabel.new(top, :text=>'self.object_id == ' <<
top.object_id.to_s).pack
  e = TkEntry.new(top).pack
  TkButton.new(top, :text=>'CLOSE',
               :command=>proc{top.withdraw; var.value = 1}).pack
  [top, e]
end

root = Tk.root
TkEntry.new.pack.focus
TkButton.new(:text=>'QUIT', :command=>proc{exit}).pack(:side=>:bottom)

b1 = TkButton.new(:text=>'onetime toplevel',
                  :command=>proc{create_onetime_toplevel(b1)}).pack

b2 = TkButton.new(:text=>'reusable toplevel').pack
wait_var = TkVariable.new

reusable_top, entry = create_reusable_toplevel(b2, wait_var)

b2.command{
  reusable_top.deiconify
  entry.focus
  reusable_top.set_grab
  wait_var.tkwait  # wait for writing to wait_var.
                   # It's similar to wait_var.wait,
                   # but tkwait checks the existence of Tk's root
window.
                   # When the root window is destroyed, tkwait will
finish.
  reusable_top.release_grab
  reusable_top.withdraw
}

Tk.mainloop
This topic is locked and can not be replied to.