Hi, 

From: "R. Mark Volkmann" <mark / ociweb.com>
Subject: Tk dialogs
Date: Thu, 9 Dec 2004 23:03:30 +0900
Message-ID: <1102600881.41b85ab18ec2d / mail.ociweb.com>
> How can I add widgets like TkEntry to a TkDialog?  I've written a class that
> inherits from TkDialog, but I can't figure out how to add widgets in the
> initialize method.  

It is possible, but a little difficult.
I recommend you to create your dialogbox class.

> Maybe that's not possible and I should use a TkFrame
> instead to implement a custom dialog box.

Here you are. ;-)  Please improve it for your purpose. 

# The sample requires tkalignbox.rb which is included at 'ext/tk/samples'
# directory in Ruby source archive.

-------------------------------------------------------------------------
require 'tk'
require 'tkalignbox'

class MyDialogBox < TkToplevel
  def _close(str)
    @status.value = str
    @top.withdraw
  end

  def initialize(parent, *btn_names) # parent, btn_name, ..., keys
    args = []

    if parent != nil && !parent.kind_of?(TkWindow)
      btn_names.unshift(parent)
      parent = nil
    end
    args << parent unless parent
    args << btn_names.pop if btn_names[-1].kind_of?(Hash)

    super(*args)

    @status = TkVariable.new

    @frame = TkFrame.new(@top).pack(:side=>:top, :fill=>:both, :expand=>true)

    @btn_frame = TkFrame.new(@top, :borderwidth=>2, :relief=>:ridge)
    @btn_frame.pack(:side=>:bottom, :fill=>:x, :expand=>true)

    @btn_box = TkHBox.new(@btn_frame, :borderwidth=>0, 
                          :padx=>7, :pady=>3).pack

    @buttons = btn_names.collect{|name|
      TkButton.new(@top, :text=>name, :command=>proc{_close(name)})
    }

    @btn_box.add(*@buttons)
  end

  def create_self(keys={})
    @top = TkToplevel.new({:widgetname=>@path}.update(keys))
    @top.protocol(:WM_DELETE_WINDOW, proc{}) # ignore
    @top.bind('Destroy'){@status.value = ''} # to exit @status.wait
    @top.withdraw
  end

  def frame
    @frame
  end

  def show(geom=nil)
    @top.geometry(geom) if geom
    @top.deiconify
    @top.resizable(false, false)
    @top.raise
    @top.grab
    @status.wait
    @top.grab_release
    @top.withdraw

    @status.value
  end
end

################################################
# test
################################################
if __FILE__ == $0
  dialog = MyDialogBox.new(*%w(ok retry cancel foo bar))
  f = dialog.frame
  l = TkLabel.new(f, :text=>'This is a sample of MyDialogBox.')
  l.pack(:padx=>100, :pady=>20, :fill=>:x)
  ff = TkFrame.new(f).pack(:padx=>10, :pady=>5, :fill=>:x, :expand=>true)
  TkLabel.new(ff, :text=>'Input:').pack(:side=>:left)
  e = TkEntry.new(ff).pack(:side=>:left, :fill=>:both, :expand=>true)

  TkButton.new(:text=>'show dialog', 
               :command=>proc{
                 e.focus
                 btn = dialog.show
                 p [btn, e.value]
               }).pack

  Tk.mainloop
end
-------------------------------------------------------------------------
-- 
Hidetoshi NAGAI (nagai / ai.kyutech.ac.jp)