"Ron Jeffries" <ronjeffries / acm.org> wrote in message news:070703DE27F35AEA.7E68E353685AFAB4.1098708902332E2B / lp.airnews.net... > Hi Gang, > > I've been through the newsgroup and the web sites and could use some > help with Tk in Windows. Does anyone have Conrad's widget demo running > on Win 2000? > > When I run widget, I get a stack problem: > > from /cygdrive/c/ruby/lib/ruby/1.6/tk.rb:811:in `_invoke' > ... 736 levels... > from ./tkencoding.rb:25:in `_invoke' > from /cygdrive/c/ruby/lib/ruby/1.6/tkafter.rb:14 > from C:\ruby\samples\tk\demos\widget:14:in `require' > from C:\ruby\samples\tk\demos\widget:14 > > This seems to be caused by requiring tkafter, if I remove that then I > get the problem a little later, caused by tkencoding. If I remove > that, I get > command not found: cat ./button.rb > which I suppose would be trivial to get around if I had a clue what > "cat' is. > > So, anyway, is there a windows version of this stuff? > > Or am I on the wrong track entirely? What I'm trying to do, with Chet > Hendrickson, is prepare for a demo we're doing at Software > Development. We just need a fairly simple GUI, with a list box, a text > box, some scrolling, simple menus, etc. > > I'm finding translating between the Perl/Tk and Ruby to be a bit hard > for those first bites. > > Thanks, > > Ron > > Ronald E Jeffries > http://www.XProgramming.com > http://www.objectmentor.com Hope this is what you are looking for, I translated the python example for figure 2.5 in the book "Python and Tkinter Programming" by John E. Grayson. It is a direct translation avoiding any changes possible (save some minor formatting). It runs on my Windows 98 box. I am using the install kit from Pragmatic Programmer's 1.6.2-3 (Custom install, all features). I commented out one line in the code since I did not know how to handle it in Ruby and the menus (other than File->Exit) report a tcl script error instead of doing nothing. You should be able to run it from DOS using "ruby alltkwidgets.rb" (if you saved it as alltkwidgets.rb that is). I also run it from inside Visual SlickEdit without trouble (having set up VSE for Ruby). First the code, then a file the code uses (the program looks for the support file as matz.txt): require "tk" class AllTkWidgets def initialize(master) @frame = TkFrame.new(master) @frame.pack end mbar = TkFrame.new(@frame, "relief"=>"raised", "bd"=>2) mbar.pack("fill"=>"x") # Create File menu filebutton = TkMenubutton.new(mbar, "text"=>"File") filebutton.pack("side"=>"left") filemenu = TkMenu.new(filebutton, "tearoff"=>0) filebutton["menu"] = filemenu # Populate File menu filemenu.add("command", "label"=>"Exit", "command"=>"exit") # Create object menu objectbutton = TkMenubutton.new(mbar, "text"=>"Object") objectbutton.pack("side"=>"left") objectmenu = TkMenu.new(objectbutton, "tearoff"=>0) objectbutton["menu"] = objectmenu # Populate object menu objectmenu.add("command", "label"=>"object", "command"=>"stub") # Create edit menu editbutton = TkMenubutton.new(mbar, "text"=>"Edit") editbutton.pack("side"=>"left") editmenu = TkMenu.new(editbutton, "tearoff"=>0) editbutton["menu"] = editmenu # Populate edit menu editmenu.add("command", "label"=>"edit", "command"=>"stub") # Create view menu viewbutton = TkMenubutton.new(mbar, "text"=>"View") viewbutton.pack("side"=>"left") viewmenu = TkMenu.new(viewbutton, "tearoff"=>0) viewbutton["menu"] = viewmenu # Populate view menu viewmenu.add("command", "label"=>"view", "command"=>"stub") # Create tools menu toolsbutton = TkMenubutton.new(mbar, "text"=>"Tools") toolsbutton.pack("side"=>"left") toolsmenu = TkMenu.new(toolsbutton, "tearoff"=>0) toolsbutton["menu"] = toolsmenu # Populate tools menu toolsmenu.add("command", "label"=>"tools", "command"=>"stub") # Create help menu helpbutton = TkMenubutton.new(mbar, "text"=>"Help") helpbutton.pack("side"=>"right") helpmenu = TkMenu.new(helpbutton, "tearoff"=>0) helpbutton["menu"] = helpmenu # Populate help menu helpmenu.add("command", "label"=>"help", "command"=>"stub") # Widgets iframe1 = TkFrame.new(@frame, "bd"=>2, "relief"=>"sunken") TkButton.new(iframe1, "text"=>"Button").pack("side"=>"left", "padx"=>5) TkCheckbutton.new(iframe1, "text"=>"CheckButton").pack("side"=>"left", "padx"=>5) v=TkVariable.new TkRadiobutton.new(iframe1, "text"=>"Button", "variable"=>v, "value"=>3).pack("side"=>"right", "anchor"=>"w") TkRadiobutton.new(iframe1, "text"=>"Dio", "variable"=>v, "value"=>2).pack("side"=>"right", "anchor"=>"w") TkRadiobutton.new(iframe1, "text"=>"Ra", "variable"=>v, "value"=>1).pack("side"=>"right", "anchor"=>"w") iframe1.pack("expand"=>true, "fill"=>"x", "pady"=>10, "padx"=>5) iframe2 = TkFrame.new(@frame, "bd"=>2, "relief"=>"ridge") TkLabel.new(iframe2, "text"=>"Label widget:").pack("side"=>"left", "padx"=>5) t = TkVariable.new e = TkEntry.new(iframe2, "textvariable"=>t, "bg"=>"white").pack("side"=>"right", "padx"=>5) e.insert(0, "Entry widget") iframe2.pack("expand"=>true, "fill"=>"x", "pady"=>10, "padx"=>5) iframe3 = TkFrame.new(@frame, "bd"=>2, "relief"=>"groove") listbox = TkListbox.new(iframe3, "height"=>4) for line in ["Listbox Entry One","Entry Two","Entry Three","Entry Four"] listbox.insert("end", line) end listbox.pack("fill"=>"x", "padx"=>5) iframe3.pack("expand"=>true, "fill"=>"x", "pady"=>10, "padx"=>5) iframe4 = TkFrame.new(@frame, "bd"=>2, "relief"=>"sunken") text=TkText.new(iframe4, "height"=>10) fd = open("matz.txt") lines = fd.read fd.close text.insert("end", lines) text.pack("side"=>"left", "fill"=>"x", "padx"=>5) sb = TkScrollbar.new(iframe4, "orient"=>"vertical", "command"=>proc{|*args| text.yview *args}) sb.pack("side"=>"right", "fill"=>"y") text.yscrollcommand(proc {|first,last| sb.set(first,last)}) iframe4.pack("expand"=>true, "fill"=>"x", "pady"=>10, "padx"=>5) iframe5 = TkFrame.new(@frame, "bd"=>2, "relief"=>"raised") TkScale.new(iframe5, "from"=>0.0, "to"=>50.0, "label"=>"Scale widget", "orient"=>"horizontal").pack("side"=>"left") c = TkCanvas.new(iframe5, "bg"=>"white", "width"=>340, "height"=>100) c.pack for i in (0..25) TkcOval.new(c, 5+(4*i),5+(3*i),(5*i)+60,(i)+60, "fill"=>"gray70") end TkcText.new(c, 260, 80, "text"=>"Canvas", "font"=>["verdana", 10, "bold"]) iframe5.pack("expand"=>true, "fill"=>"x", "pady"=>10, "padx"=>5) iframen = TkFrame.new(@frame, "bd"=>2, "relief"=>"flat") TkMessage.new(iframen, "text"=>"This is a Message widget", "width"=>300, "relief"=>"sunken").pack("fill"=>"x", "padx"=>5) iframen.pack("expand"=>true, "fill"=>"x", "pady"=>10, "padx"=>5) def stub end end root = TkRoot.new #root.option_add("*font", ["verdana", 10, "bold"]) all = AllTkWidgets.new(root) root.title("Tk Widgets in Ruby") root.mainloop The matz.txt file: What's Ruby Ruby is the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, extensible, and portable. Oh, I need to mention, it's totally free, which means not only free of charge, but also freedom to use, copy, modify, and distribute it. Features of Ruby Ruby has simple syntax, partially inspired by Eiffel and Ada. Ruby has exception handling features, like Java or Python, to make it easy to handle errors. Ruby's operators are syntax sugar for the methods. You can redefine them easily. Ruby is a complete, full, pure object oriented language: OOL. This means all data in Ruby is an object, not in the sense of Python or Perl, but in the sense of Smalltalk: no exceptions. Example: In Ruby, the number 1 is an instance of class Fixnum. Ruby's OO is carefully designed to be both complete and open for improvements. Example: Ruby has the ability to add methods to a class, or even to an instance during runtime. So, if needed, an instance of one class *can* behave differently from other instances of the same class. Ruby features single inheritance only, *on purpose*. But Ruby knows the concept of modules (called Categories in Objective-C). Modules are collections of methods. Every class can import a module and so gets all its methods for free. Some of us think that this is a much clearer way than multiple inheritance, which is complex, and not used very often compared with single inheritance (don't count C++ here, as it has often no other choice due to strong type checking!). Ruby features true closures. Not just unnamed function, but with present variable bindings. Ruby features blocks in its syntax (code surrounded by '{' ... '}' or 'do' ... 'end'). These blocks can be passed to methods, or converted into closures. Ruby features a true mark-and-sweep garbage collector. It works with all Ruby objects. You don't have to care about maintaining reference counts in extension libraries. This is better for your health. ;-) Writing C extensions in Ruby is easier than in Perl or Python, due partly to the garbage collector, and partly to the fine extension API. SWIG interface is also available. Integers in Ruby can (and should) be used without counting their internal representation. There *are* small integers (instances of class Fixnum) and large integers (Bignum), but you need not worry over which one is used currently. If a value is small enough, an integer is a Fixnum, otherwise it is a Bignum. Conversion occurs automatically. Ruby needs no variable declarations. It uses simple naming conventions to denote the scope of variables. Examples: simple 'var' = local variable, '@var' = instance variable, '$var' = global variable. So it is also not necessary to use a tiresome 'self.' prepended to every instance member. Ruby can load extension libraries dynamically if an OS allows. Ruby features OS independent threading. Thus, for all platforms on which Ruby runs, you also have multithreading, regardless of if the OS supports it or not, even on MS-DOS! ;-) Ruby is highly portable: it is developed mostly on Linux, but works on many types of UNIX, DOS, Windows 95/98/NT, Mac, BeOS, OS/2, etc. The Creator of Ruby Yukihiro Matsumoto, a.k.a Matz matz / netlab.co.jp