CSC/ECE 517 Fall 2010/ch1 S10 MS: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(60 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''GUI Toolkit For Ruby'''
'''GUI Toolkit for Ruby'''




Line 6: Line 6:




[http://en.wikipedia.org/wiki/Widget_toolkit/ GUI toolkit] is a collection of set of [http://en.wikipedia.org/wiki/Application_programming_interface API's] which will produce graphical user interface [http://en.wikipedia.org/wiki/Graphical_user_interface (GUI)] for the end users to interact with. Generally, this toolkit creates separate windows, each with one application that makes use of a particular [http://en.wikipedia.org/wiki/Web_widget widget].  Ruby is an object oriented dynamically typed programming language. It is used extensively for developing web applications (mostly with Rails) and for utility scripting. Initially RUBY was not a well known language for developing desktop application GUIs as it did not have good GUI libraries.  With developments in Shoes, wxRuby, FXRub etc which are ruby library for creating web like desktop applications, Ruby GUI started picking up and became increasingly popular. Shoe is the most popular among all of these. This article describes different types of ruby GUI toolkits, their uses and their pros and cons.
[http://en.wikipedia.org/wiki/Widget_toolkit/ GUI toolkit] is a collection of [http://en.wikipedia.org/wiki/Application_programming_interface API's] that helps in developing Graphical User Interface[http://en.wikipedia.org/wiki/Graphical_user_interface (GUI)] for web based or desktop applications. Generally, this toolkit creates separate windows, each with one application that makes use of a particular [http://en.wikipedia.org/wiki/Web_widget widget].  Ruby is an object oriented dynamically typed programming language. It is used extensively for developing web applications (mostly with Rails) and for utility scripting. Initially RUBY was not a well known language for developing desktop application GUIs as it did not have good GUI libraries.  With developments in Shoes, wxRuby, FXRuby etc which are ruby libraries for creating web like desktop applications, Ruby GUI started picking up and became increasingly popular. Shoes is the most popular among all of these. This article describes different types of ruby GUI toolkits, their uses and their pros and cons.
 
Ruby is a very useful language for writing end user application and most of the present day end user application makes use of GUI.  The main advantage of Ruby is that it enables [http://en.wikipedia.org/wiki/Rapid_application_development Rapid Application Development].  Unlike the time consuming traditional programming languages where you code, compile and then test, Ruby scripts can be quickly and  easily changed to try new ideas. This is a big advantage when developing GUI applications using Ruby. The user interface can be constructed incrementally, adding new elements and then re-running the program to see how the user interface has changed 


Ruby is a very useful language for writing end user application and most of the present day end user application makes use of GUI.  The main advantage of Ruby is that it enables [http://en.wikipedia.org/wiki/Rapid_application_development Rapid Application Development].  Unlike the time consuming traditional programming languages where you code, compile and then test, Ruby scripts can be quickly and easily changed to try new ideas. This is a big advantage when developing GUI applications using Ruby. The user interface can be constructed incrementally, adding new elements and then re-running the program to see how the user interface has changed


= '''Different Ruby GUI toolkits''' =
= '''Different Ruby GUI toolkits''' =




Ruby does not have any real GUI System. The default GUI Toolkit used is Tk. Shoes is the most recent toolkit being used for Ruby. But the most advantageous among all is agreed to be wxRuby2.
There are plenty of Ruby GUI toolkits to choose from depending on applications being developed. Each has its own advantages and disadvantages. Tk is the oldest GUI toolkit among others. Shoes is the most recent one developed. WxRuby is the widely used toolkit.  




=='''Tk'''==
=='''Tk'''==


Tk, which is a standard and [http://en.wikipedia.org/wiki/Cross-platform cross platform] GUI for ruby was used to develop desktop apps. It is generally installed by the Ruby Installer itself and has a complete documented [[API]]. It is relatively old, does not care about appearances and is suitable only for simple GUI applications. But it is perfectly functional and is also easily available. It was not well documented and was not object oriented.  
Tk, which is a standard and [http://en.wikipedia.org/wiki/Cross-platform cross platform] GUI for ruby was used to develop desktop applications. It is generally installed by the Ruby Installer itself and has a complete documented API. It is relatively old, does not care about appearances and is suitable only for simple GUI applications. But it is perfectly functional and is also easily available.


==='''Sample HelloWorld Program using Tk'''===
==='''Sample Hello World Program using Tk'''===  


require 'tk'
  require 'tk'
  msg = TkRoot.new { title “Hello World!” }
      msg = TkRoot.new {title “Hello World!”}
Tk.mainloop
  Tk.mainloop


It is mandatory to instruct Ruby that it should "require tk" and "Tk.mainloop",which is the [[event handler]], is needed to start the GUI. All subsequent widgets will be contained in the root if their parent class is not specified.
require loads the Tk ruby extension. TkRoot is similar to Object class. Every toolkit is extended from the root. Its a starter for the GUI


[http://ruby.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=ruby&cdn=compute&tm=113&f=10&tt=14&bt=0&bts=1&zu=http%3A//www.meshplex.org/wiki/Ruby/Basic_GUI[1]]
It is mandatory to instruct Ruby that it should "require tk" and "Tk.mainloop", which is the [http://en.wikipedia.org/wiki/Event_handler event handler], is needed to start the GUI. All subsequent widgets will be contained in the root if their parent class is not specified [1].


[[Image:Hello World.jpg]]
[[Image:first.jpg]]


==='''Getting and Setting Options'''===
==='''Getting and Setting Options'''===  


To proceed to a more detailed application, let us look at the following code -
To proceed to a more detailed application, let us look at the following code - [2]


require 'tk'
  require 'tk'
    root = TkRoot.new do
      title "Hello world!"
      minsize(250,250)
    end
   
   
root = TkRoot.new do
    l1 = TkLabel.new(root) do
title "Hello world!"
      text 'Hello world!'
minsize(250,250)
      background 'blue'
end
      pack { padx 15; pady 15; }
    end
   
   
l1 = TkLabel.new(root) do
  Tk.mainloop
text 'Hello world!'
 
background 'blue'
pack { padx 15; pady 15; }
end
Tk.mainloop


[http://ruby.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=ruby&cdn=compute&tm=113&f=10&tt=14&bt=0&bts=1&zu=http%3A//www.meshplex.org/wiki/Ruby/Basic_GUI[2]]


This creates a window of the specified size with the title Hello World and embeds a widget - Label,  with the text Hello World and the background in blue. The 'pack' is called the [[geometry manager]] and specifies the pixel co-ordinates along with the justification of the text inside. It usually takes [[hash arguments]].  
This creates a window of the specified size with the title Hello World and embeds a widget - Label,  with the text Hello World and the background in blue. The 'pack' is called the geometry manager and specifies the pixel co-ordinates along with the justification of the text inside. It usually takes hash arguments.  


[[Image:Label.jpg]]
[[Image:sample label.jpg]]


It is also possible to change the setting of options dynamically.  
It is also possible to change the setting of options dynamically.  
Line 62: Line 60:
Example -
Example -


command proc { ll.configure('text'=>"Bye Bye") }
  command proc { ll.configure('text'=>"Bye Bye") }
 
The 'configure' method will change the text output to "Bye Bye" over writing "Hello World" [3].
 


The 'configure' method will change the text output to "Bye Bye" over writing "Hello World".  
After we create a widget AND SET ITS OPTIONS, it is necessary most of the time to get back data from it. This is done by using callback. Getting back data means to get back a '0' or '1' depending on whether the required application does what it is meant to do. Using callback, a proc Object is created which is called as soon as the callback starts.


[http://ruby-doc.org/docs/ProgrammingRuby/[3]]
Example -  


==='''CallBack and Binding Variables'''===
  TkLabel.new()
  {
    text "Hi"
    command proc {l appcheck.value; exit }
  }


After we create a widget, it is necessary most of the time to get back data from it. This is done by using callback. Getting back data means to get back a '0' or '1' depending on whether the required application does what it is meant to do. Using callback, a proc Object is created which is called as soon as the callback starts.
The same thing is achieved by binding variables where a reference is created using TkVariable. This reference is then passed as an argument to the 'variable' option and output is obtained after the check [4].


Example -
  appcheck = TkVariable.new
  TkCheckButton.new()
  {
    variable mycheck
  }


TkLabel.new()
This action of getting data can also be achieved dynamically using the cget(arg) method.  
{ text "Hi"
  command proc {l appcheck.value; exit }
}


The same thing is achieved by binding variables where a reference is created using TkVariable. This reference is then passed as an argument to the 'variable' option and output is obtained after the check.
  require 'tk'
  l = TkLabel.new
  {
    text    "Good Morning"
    color    "black"
  }
  l.cget('text')  » "Good Morning"
  l.cget('color') » "black"


appcheck = TkVariable.new
==='''Benefits'''===


* Cross Platform GUI
* Easy application development
* Available easily.


TkCheckButton.new() {
==='''Drawbacks'''===
  variable mycheck
  }


This action of getting data can also be acheived dynamically using the cget(arg) method.
* Documentation is not good
* Do not have good appearance
* Can be used only for simple application
* No support for native widgets


require 'tk'
More information about Tk as GUI Toolkit and example programs can be found in the book [5].
l = TkLabel.new {
  text    "Good Morning"
  color    "black"
}
l.cget('text') » "Good Morning"
l.cget('color') » "black"


[http://ruby-doc.org/docs/ProgrammingRuby/[4]]
=='''FxRuby'''==
 


==='''Canvas'''===
This is another powerful GUI toolkit for Ruby that helps in developing user interfaces easily and effectively.  It makes use of [http://en.wikipedia.org/wiki/Fox_toolkit Free Objects for X (FOX) toolkit] which is a C++ open source library.  This uses the powerful features of Ruby at the same time takes benefits of functionality and performance of greatly optimized C++ toolkit.  Unlike Tk, none of the Linux distributions include FOX as a standard installation package. A prerequisite for programming with FXRuby is to have a working FOX installation after which the FXRuby source code can be downloaded from the FXRuby home page, and build and install that extension module.


The Canvas widget is used to draw any picture you want by mere pressing of a button and the movement of the mouse in which ever direction you want to. Once the button is released, a Post Script, which is nothing but the image drawn, is displayed. It is generally used if you want to draw large size pictures like outline of a house, single line diagram of any instrument or just a random drawing.
==='''Sample Hello World Program using FxRuby'''===


==='''Scrolling'''===
The hello.rb program can be used  as an example for understanding the basics of FXRuby program  [15].


This is generally used when a subset or a smaller portion of an image is needed to work with. In that case, we set up scrollbars for the required class. The movement of the scroll bar changes the widget view and vice versa. Hence, they are inter-dependent or bidirectional.
  #!/usr/bin/env ruby
  require 'fox16'
  include Fox
    application = FXApp.new("Hello", "FoxTest")
    main = FXMainWindow.new(application, "Hello", nil, nil, DECOR_ALL)
    FXButton.new(main, "&Hello, World!", nil, application, FXApp::ID_QUIT)
    application.create()
    main.show(PLACEMENT_SCREEN)
    application.run()


More information about Tk as GUI Toolkit and example programs can be found in the book [http://ruby-doc.org/docs/ProgrammingRuby/[5]]
require loads the foxruby application. Fxapp is the programs instance created after which a new button with " Hello World" is created. Then the application is run and the message is displayed.


=='''FxRuby'''==
[[Image:foxapp.jpg]]
 
 
==='''Getting and Setting Options'''===


This is another powerful GUI toolkit for Ruby that helps in developing user interfaces easily and effectively. It makes use of [http://en.wikipedia.org/wiki/Fox_toolkit Free Objects for X (FOX) toolkit] which is a C++ open source library.  This uses the powerful features of Ruby at the same time takes benefits of functionality and performance of greatly optimized C++ toolkit. Unlike Tk, none of the Linux distributions include FOX as a standard installation package. A prerequisite for programming with FXRuby is to have a working FOX installation after which the FXRuby source code can be downloaded from the FXRuby home page, and build and install that extension module.
The options can be passed into the class's new method when the object is first instantiated. They can usually also be changed after the object exists through some object-specific accessor method. For example, the options for an FXButton can be get or set via the FXButton#buttonStyle accessor methods.  


==='''Sample HelloWorld Program using FxRuby'''===


The hello.rb program can be used  as an example for understanding the basics of FXRuby program.
==='''Benefits'''===
#!/usr/bin/env ruby


require 'fox16'
* Easy to install and use
* Well documented


include Fox
==='''Drawbacks'''===


application = FXApp.new("Hello", "FoxTest")
* Light weight when compared to WxRuby which is more fully featured
main = FXMainWindow.new(application, "Hello", nil, nil, DECOR_ALL)
* Instead of using native widgets, it draws its own widgets on every platform
FXButton.new(main, "&Hello, World!", nil, application, FXApp::ID_QUIT)
application.create()
main.show(PLACEMENT_SCREEN)
application.run()


[[Image:Hello.jpg]]


More information on FoxRuby can be obtained from [18].


=='''Qt/Qt4'''==
=='''Qt/Qt4'''==


Qt is one of the leading toolkits for creating graphical user interfaces using Ruby programming language.  
Qt is one of the leading cross-platform toolkits for creating web-enabled desktop, mobile and embedded GUI applications. It has Intuitive C++ class library. Web-enabled applications can be written once and deployed across desktop, mobile and embedded operating systems without rewriting the source code. It has high runtime performance with portability across desktop and embedded operating systems.
 
==='''Sample Hello World Program using Qt'''===
 
The hello.rb program can be used  as an example for understanding the basics of QtRuby program [16].
 
  require 'Qt4'
    app = Qt::Application.new(ARGV)
    hello = Qt::PushButton.new('Hello World!')
    hello.resize(100, 30)
    hello.show()
  app.exec()
 
 
This code initially loads the QtRuby extension.The app is the programs instance that is created here. A push button for "Hello World is created". The button is set up to be 100 pixels wide and 30 pixels high. the show() is called to make the widget visible as it is always invisible when created. Finally Qt receives and processes user and system events and passes these on to the appropriate widgets.
 
 
 
[[Image:qthellofirst.jpg]]
 
==='''Getting and Setting Options'''===
 
All Qt setters begin with the word set, such as Qt::Widget::setMinimumSize and all getters begin with get. This can be overridden in Ruby by dropping the set and using assignment. This means the following three statements are equivalent:
 
widget.setMinimumSize(50)
widget.minimumSize = 50    # same
widget.minimum_size = 50    # same


==='''Sample HelloWorld Program using Qt'''===


require 'Qt4'
==='''Benefits'''===
* Available on MS Windows, Mac, and GNU/Linux (under commercial license)
* Has a full-featured embeddable GUI
* Offers reliable commercial support


app = Qt::Application.new(ARGV)


hello = Qt::PushButton.new('Hello World!')
==='''Drawbacks'''===
hello.resize(100, 30)
hello.show()


app.exec()
* Even though a gem is available for the Windows installation. only source code is available for other platforms.
* Costly preventing large scale adoption.
* Because Qt is a C++ toolkit, some idioms are used in the toolkit that are necessary due to constraints in the language.


[[Image:Hello World(1).jpg]]


More information about QtRuby and its usage can be obtained from [17].


=='''WxRuby2'''==
=='''WxRuby2'''==
Line 156: Line 201:
WxRuby is an open source GUI toolkit for Ruby programming language. It allows creating cross platform desktop applications. It makes use of the C++ [http://en.wikipedia.org/wiki/ WxWidgetswxWidgets] GUI framework.  WxWidgets is an open source cross platform library in C++ that aids in creating application for Windows, OS X, Linux and UNIX on 32-bit and 64-bit architectures. It binds languages like python, perl, ruby etc. It has several advantages over other ruby GUI toolkits.  Being cross- platform , it has many advanced features with native look and feel. End users do not have to adjust to foreign interface. It is used by many users and actively developed with Unicode support
WxRuby is an open source GUI toolkit for Ruby programming language. It allows creating cross platform desktop applications. It makes use of the C++ [http://en.wikipedia.org/wiki/ WxWidgetswxWidgets] GUI framework.  WxWidgets is an open source cross platform library in C++ that aids in creating application for Windows, OS X, Linux and UNIX on 32-bit and 64-bit architectures. It binds languages like python, perl, ruby etc. It has several advantages over other ruby GUI toolkits.  Being cross- platform , it has many advanced features with native look and feel. End users do not have to adjust to foreign interface. It is used by many users and actively developed with Unicode support


==='''Sample HelloWorld Program using WxRuby2 '''===
==='''Sample Hello World Program using WxRuby2 '''===


require 'wx'
  require 'wx'
   
   
class MyApp < Wx::App
  class MyApp < Wx::App
  def on_init
    def on_init
    @frame = Wx::Frame.new( nil, -1, "Application" )
      @frame = Wx::Frame.new( nil, -1, "Hello World" )
    @frame.show
      @frame.show
    end
   end
   end
end
   
   
app = MyApp.new
  app = MyApp.new
app.main_loop
  app.main_loop
 
The class inherits from the app class of WXruby. The on_init method of a Wx::App class is run before the main loop of that application is entered. parent widget is the first parameter of the constructor. The second parameter of widget constructors is an id field. The third parameter of the Wx::Frame constructor is the text to display in the title .


'wx' module is required to load WxRuby library. The class containing all the WxRuby applications must be inherited from the Wx::App class.
'wx' module is required to load WxRuby library. The class containing all the WxRuby applications must be inherited from the Wx::App class.
The on_init method is used to create any widget. The widget Frame here has three arguments (parent class, unique ID number, text to be displayed). The 'show' method has to be called for the Frame to be displayed.  
The on_init method is used to create any widget. The widget Frame here has three arguments (parent class, unique ID number, text to be displayed). The 'show' method has to be called for the Frame to be displayed [6].
 
==='''Getting and Setting Options'''===
 
C++ and Java conventions are used for naming the methods for getting and setting properties using wxWidgets API. For example, In C++ style,to get and set the size of a widget, the methods are named :


[http://ruby.about.com/od/gui/qt/wxrubyworld.htm [6]]
  widget.get_size
  widget.set_size(new_size)
 
In Ruby, methods are named simply after the property. Therefore, in wxRuby, the following are valid alternatives to the above: [19]
 
  widget.size
  widget.size = new_size


==='''Creating Menu'''===
==='''Creating Menu'''===
Line 186: Line 243:
Wx::ID_HIGHEST -> If any ID is higher than the HIGHEST, it creates no conflict with internal ID.
Wx::ID_HIGHEST -> If any ID is higher than the HIGHEST, it creates no conflict with internal ID.


'append' -> It adds a menu item to the menu bar. Usually takes three arguments (ID, text to be displayed, keyboard shortcut, short 
'append' - It adds a menu item to the menu bar. Usually takes three arguments - ID, text to be displayed, keyboard shortcut.
            description (optional)) . The menu is appended by using two arguments (menu object, name of object)
 


Example -  
Example - [7]


Creating a Help Menu -
Creating a Help Menu -
help = Wx::Menu.new
  help = Wx::Menu.new
help.append( Wx::ID_ABOUT, "&About...\tF1", "Show about dialog" )
  help.append( Wx::ID_ABOUT, "&About...\tF1", "Show about dialog" )
menu.append( help, "&Help" )
  menu. append( help, "&Help" )


[http://ruby.about.com/od/gui/qt/wxrubymenu.htm [7]]
==='''Benefits'''===
* Stable and complete GUI toolkit
* Consistent look and feel because of the usage of native widgets
* Good support for all platforms
* WxWidgets has bindings for python, perl, java, lua, eiffel, C# (.NET), basic and ruby


==='''Adding Status Bar'''===
==='''Drawbacks'''===


Status Bar is used to display any description of the option over which the mouse moves. The Status Bar Object can be created and assigned using status_bar attribute. Hence, there is no need for any variable and it can be retrieved anytime. It is generally manipulated as a stack where the displayed message is pushed to the stack and once finished, it is popped out. Top-most is usually displayed and after pop, the original message becomes the top-most.
* Even though it has bindings for other languages, the API is mostly C++ oriented
* WxWidgets tries to support a very expansive feature set, and as a result, some lesser-used components of the toolkit are not as stable/reliable as commonly used components are
* It does not provide binaries for any system.  
* It has to be compiled manually




Example -
status = Wx::StatusBar.new(self)
status.push_status_text "Status is shown here"
 
[http://ruby.about.com/od/wxruby/qt/wxstatusbar.htm [8]]
==='''Arranging Widgets'''===
It can be done either by '''absolute positioning''' or by using '''layout managers''' called ''sizers''.
In the former, size, position and shape of every widget needs to be defined individually and manually which has the following disadvantages -
1. Resizing becomes impossible
2. Adding Widgets is difficult
3. Difficult to change font size
4. Manual work out of size and shape of widget causing overlapping.
Hence, it is better to use sizers where any changes are automatically taken care of.
Sizers are classified as Box and Grid. Use Wx::BoxSizer class for Box.
More information and example programs can be obtained from the tutorial [http://wxruby.rubyforge.org/wiki/wiki.pl? [9]]


More information and example programs can be obtained from the tutorial [9]


=='''Shoes'''==
=='''Shoes'''==
Line 233: Line 275:
==='''Sample Hello World Program using Shoes'''===
==='''Sample Hello World Program using Shoes'''===


Shoes.app :width => 250, :height => 100 do
  Shoes.app :width => 250, :height => 100 do
  para "Hello World!"
    para "Hello World!"
end
  end
    
    
The Shoes.app is the method which encapsulates the entire application and it takes width and height, in pixels, as parameters. Inside this method, any options can be set. Here, 'para' is a text container used to display the text "Hello World". 'para' can also take multiple arguments. Formatting is possible by inserting the format operation even inside the 'para'. It is also possible to include other text containers such as 'title', 'subtitle', 'tagline', 'caption' etc.  
The Shoes.app is the method which encapsulates the entire application and it takes width and height, in pixels, as parameters. Inside this method, any options can be set. Here, 'para' is a text container used to display the text "Hello World". 'para' can also take multiple arguments. Formatting is possible by inserting the format operation even inside the 'para'. It is also possible to include other text containers such as 'title', 'subtitle', 'tagline', 'caption' etc [10].


[http://ruby.about.com/od/shoes/ss/shoes1_2.htm [10]]
[[Image:Shoes.Hello World.jpg]]


[[Image:shoeapp.jpg]]


'''Stack and Flow'''  
'''Stack and Flow'''  
Line 250: Line 290:
Example -
Example -


Shoes.app :width => 400, :height => 140 do
  Shoes.app :width => 400, :height => 140 do
  flow :width => 250 do
    flow :width => 250 do
  button "Button 1"
    button "Button 1"
  button "Button 2"
    button "Button 2"
  button "Button 3"
    button "Button 3"
   end
   end


[[Image:123.jpg]]


Replace 'flow' by 'stack' to get the stack of buttons. By default, the arrangement of the tools is 'flow'.
Replace 'flow' by 'stack' to get the stack of buttons. By default, the arrangement of the tools is 'flow'[11]


[http://ruby.about.com/od/shoes/ss/shoes2.htm [11]]
[[Image:flow app.jpg]]


Images can be displayed, resized, set as background using 'stack' and 'flow'. It is also possible to provide the URL and the corresponding image is placed in the window.
Images can be displayed, resized, set as background using 'stack' and 'flow'. It is also possible to provide the URL and the corresponding image is placed in the window.


Example -
Example - [12]


stack do
  stack do
    image 'lilies.jpg'
    image 'lilies.jpg', :width => '150%'
    'background 'background.jpg'' # This has to be provided before all other statements. Otherwise, it overwrites them.
  end


image 'lilies.jpg'
image 'lilies.jpg', :width => '150%'
'background 'background.jpg'' # This has to be provided before all other statements. Otherwise, it overwrites them.
end


[http://ruby.about.com/od/shoes/ss/shoes4_1.htm [12]]
==='''Benefits'''===


Shoes has some advantages and disadvantages. It has good graphics, simple interface, and control at a lower level. It can be used to distribute redistributables, used to have examples available. Disadvantages are-  maintainer AWOL, still rough around the edges since it attempts to support so many platforms. Lacks many of the more robust widgets common in other toolkit
* Good graphics
* Simple interface  
* Control at a lower level


More information and examples about using Shoes GUI Toolkit for Ruby can be found at [http://ruby.about.com/od/shoes/Shoes.htm [13]]
==='''Drawbacks'''===
* Rough around the edges since it attempts to support so many platforms.  
* Lacks many of the more robust widgets common in other toolkit


More information and examples about using Shoes GUI Toolkit for Ruby can be found at [13]


=== '''Other Ruby GUI toolkits'''===
== '''Other Ruby GUI toolkits'''==




GTK -  Stable, Well Documented, used for [[Gnome]] problems. Requires hefty set of run time libraries.
GTK -  Stable, Well Documented, used for [http://en.wikipedia.org/wiki/GNOME Gnome] problems. Requires hefty set of run time libraries.
   
   
FLTK -  
FLTK - Ruby/FLTK is a Ruby binding for FLTK. Very fast and lightweight GUI toolkit. Can produce smallest binaries of all free toolkits here. But it is outdated and has unmaintained UTF8 patch and unicode patch.
 
SWin/VRuby -


Ruby-Cocoa bridge - This is an open source project that produces web applications with MAC look and feel by combining features of Ruby and objective C programming languages. But this is not widely used because RubyCocoa applications are very slow due to the added overhead of object conversion.


== '''Conclusion''' ==
= '''Conclusion''' =


Ruby is a [http://en.wikipedia.org/wiki/Multi-paradigm_programming_language#Multi-paradigm_programming_language multi-paradigm programming language].  It not only supports web application programming, but  is a good programming language to write cross platform GUI applications. There are lot of GUI toolkit  supported by Ruby from which one can choose to develop their web/desktop application.  TkRuby is one of the old cross platform GUI toolkit.  WxRuby is a very  stable toolkit with a good selection of widgets. QtRuby being a multiplatform toolkit provides interface for Mac, Windows and Unix Operating systems.  Fxruby incorporates the functionality of a featureful, highly optimized C++ toolkit. Shoes is a simplified GUI toolkit that creates native applications with a Web feel. These toolkits have their own advantages and disadvantages. It is good to experiment with several GUI toolkits and then choose the one that looks like the best fit for what is trying to be accomplished.


= '''References''' =


* Dave Thomas, with Chad Fowler and Andy Hunt [http://pragprog.com/titles/ruby/programming-ruby ''Programing Ruby''], the Pragmatic Programmers, LLC, 2005


== '''References''' ==
* Julian Smart, Kevin Hock, Stefan Csomor [http://books.google.com/books?id=CyMsvtgnq0QC&dq=Cross-Platform+GUI+Programming+with+wxWidgets&printsec=frontcover&source=bn&hl=en&ei=ls-FTIWIGsWqlAfNj_kQ&sa=X&oi=book_result&ct=result&resnum=4&ved=0CCcQ6AEwAw#v=onepage&q&f=false ''Cross-Platform GUI Programming with wxWidgets''] Prentice Hall PTR, 2006


* Caleb Tennis [http://pragprog.com/titles/ctrubyqt/rapid-gui-development-with-qtruby ''Rapid GUI Development with QtRuby''] the Pragmatic Programmers, LLC, 2005


* Lyle Johnson [http://www.pragprog.com/titles/fxruby/fxruby ''Create Lean and Mean FxRuby GUIs''], the Pragmatic Programmers, LLC, 2008


== '''External Links''' ==
= '''External Links''' =


[http://ruby.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=ruby&cdn=compute&tm=113&f=10&tt=14&bt=0&bts=1&zu=http%3A//www.meshplex.org/wiki/Ruby/Basic_GUI]  Hello World Window using Tk
[http://ruby.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=ruby&cdn=compute&tm=113&f=10&tt=14&bt=0&bts=1&zu=http%3A//www.meshplex.org/wiki/Ruby/Basic_GUI]  Hello World Window using Tk
Line 329: Line 377:


[http://kylecordes.com/2007/ruby-gui-toolkits] ruby GUI toolkit
[http://kylecordes.com/2007/ruby-gui-toolkits] ruby GUI toolkit
[http://www.fxruby.org/doc/examples.html] Hello World program using FxRuby
[http://www.darshancomputing.com/qt4-qtruby-tutorial/chapter_01] Hello World program using QtRuby
[http://book.opensourceproject.org.cn/lamp/ruby/rubyway2nd/opensource/0768667208/ch12lev1sec4.html] QtRuby Tutorial
[http://www.fxruby.org/doc/api/] FoxRuby Documentation Tutorial
[http://wxruby.rubyforge.org/doc/wxruby_intro.html] Wxruby Overview

Latest revision as of 21:27, 16 September 2010

GUI Toolkit for Ruby


Introduction

GUI toolkit is a collection of API's that helps in developing Graphical User Interface(GUI) for web based or desktop applications. Generally, this toolkit creates separate windows, each with one application that makes use of a particular widget. Ruby is an object oriented dynamically typed programming language. It is used extensively for developing web applications (mostly with Rails) and for utility scripting. Initially RUBY was not a well known language for developing desktop application GUIs as it did not have good GUI libraries. With developments in Shoes, wxRuby, FXRuby etc which are ruby libraries for creating web like desktop applications, Ruby GUI started picking up and became increasingly popular. Shoes is the most popular among all of these. This article describes different types of ruby GUI toolkits, their uses and their pros and cons.

Ruby is a very useful language for writing end user application and most of the present day end user application makes use of GUI. The main advantage of Ruby is that it enables Rapid Application Development. Unlike the time consuming traditional programming languages where you code, compile and then test, Ruby scripts can be quickly and easily changed to try new ideas. This is a big advantage when developing GUI applications using Ruby. The user interface can be constructed incrementally, adding new elements and then re-running the program to see how the user interface has changed

Different Ruby GUI toolkits

There are plenty of Ruby GUI toolkits to choose from depending on applications being developed. Each has its own advantages and disadvantages. Tk is the oldest GUI toolkit among others. Shoes is the most recent one developed. WxRuby is the widely used toolkit.


Tk

Tk, which is a standard and cross platform GUI for ruby was used to develop desktop applications. It is generally installed by the Ruby Installer itself and has a complete documented API. It is relatively old, does not care about appearances and is suitable only for simple GUI applications. But it is perfectly functional and is also easily available.

Sample Hello World Program using Tk

 require 'tk'
     msg = TkRoot.new {title “Hello World!”}
 Tk.mainloop

require loads the Tk ruby extension. TkRoot is similar to Object class. Every toolkit is extended from the root. Its a starter for the GUI

It is mandatory to instruct Ruby that it should "require tk" and "Tk.mainloop", which is the event handler, is needed to start the GUI. All subsequent widgets will be contained in the root if their parent class is not specified [1].

Getting and Setting Options

To proceed to a more detailed application, let us look at the following code - [2]

 require 'tk'
    root = TkRoot.new do
      title "Hello world!" 
      minsize(250,250)
    end

    l1 = TkLabel.new(root) do
      text 'Hello world!'
      background 'blue'
      pack { padx 15; pady 15; }
    end

 Tk.mainloop


This creates a window of the specified size with the title Hello World and embeds a widget - Label, with the text Hello World and the background in blue. The 'pack' is called the geometry manager and specifies the pixel co-ordinates along with the justification of the text inside. It usually takes hash arguments.

It is also possible to change the setting of options dynamically.

Example -

 command proc { ll.configure('text'=>"Bye Bye") }

The 'configure' method will change the text output to "Bye Bye" over writing "Hello World" [3].


After we create a widget AND SET ITS OPTIONS, it is necessary most of the time to get back data from it. This is done by using callback. Getting back data means to get back a '0' or '1' depending on whether the required application does what it is meant to do. Using callback, a proc Object is created which is called as soon as the callback starts.

Example -

 TkLabel.new()
 { 
    text "Hi"
    command proc {l appcheck.value; exit }
 }

The same thing is achieved by binding variables where a reference is created using TkVariable. This reference is then passed as an argument to the 'variable' option and output is obtained after the check [4].

 appcheck = TkVariable.new
 TkCheckButton.new() 
 {
   variable mycheck
 }

This action of getting data can also be achieved dynamically using the cget(arg) method.

 require 'tk'
 l = TkLabel.new 
 {
   text     "Good Morning"
   color    "black"
 }
 l.cget('text')  » 	"Good Morning"
 l.cget('color') » 	"black"

Benefits

  • Cross Platform GUI
  • Easy application development
  • Available easily.

Drawbacks

  • Documentation is not good
  • Do not have good appearance
  • Can be used only for simple application
  • No support for native widgets

More information about Tk as GUI Toolkit and example programs can be found in the book [5].

FxRuby

This is another powerful GUI toolkit for Ruby that helps in developing user interfaces easily and effectively. It makes use of Free Objects for X (FOX) toolkit which is a C++ open source library. This uses the powerful features of Ruby at the same time takes benefits of functionality and performance of greatly optimized C++ toolkit. Unlike Tk, none of the Linux distributions include FOX as a standard installation package. A prerequisite for programming with FXRuby is to have a working FOX installation after which the FXRuby source code can be downloaded from the FXRuby home page, and build and install that extension module.

Sample Hello World Program using FxRuby

The hello.rb program can be used as an example for understanding the basics of FXRuby program [15].

 #!/usr/bin/env ruby
 require 'fox16'
 include Fox
   application = FXApp.new("Hello", "FoxTest")
   main = FXMainWindow.new(application, "Hello", nil, nil, DECOR_ALL)
   FXButton.new(main, "&Hello, World!", nil, application, FXApp::ID_QUIT)
   application.create()
   main.show(PLACEMENT_SCREEN)
   application.run()

require loads the foxruby application. Fxapp is the programs instance created after which a new button with " Hello World" is created. Then the application is run and the message is displayed.


Getting and Setting Options

The options can be passed into the class's new method when the object is first instantiated. They can usually also be changed after the object exists through some object-specific accessor method. For example, the options for an FXButton can be get or set via the FXButton#buttonStyle accessor methods.


Benefits

  • Easy to install and use
  • Well documented

Drawbacks

  • Light weight when compared to WxRuby which is more fully featured
  • Instead of using native widgets, it draws its own widgets on every platform


More information on FoxRuby can be obtained from [18].

Qt/Qt4

Qt is one of the leading cross-platform toolkits for creating web-enabled desktop, mobile and embedded GUI applications. It has Intuitive C++ class library. Web-enabled applications can be written once and deployed across desktop, mobile and embedded operating systems without rewriting the source code. It has high runtime performance with portability across desktop and embedded operating systems.

Sample Hello World Program using Qt

The hello.rb program can be used as an example for understanding the basics of QtRuby program [16].

 require 'Qt4'
    app = Qt::Application.new(ARGV)
    hello = Qt::PushButton.new('Hello World!')
    hello.resize(100, 30)
    hello.show()
 app.exec()


This code initially loads the QtRuby extension.The app is the programs instance that is created here. A push button for "Hello World is created". The button is set up to be 100 pixels wide and 30 pixels high. the show() is called to make the widget visible as it is always invisible when created. Finally Qt receives and processes user and system events and passes these on to the appropriate widgets.


Getting and Setting Options

All Qt setters begin with the word set, such as Qt::Widget::setMinimumSize and all getters begin with get. This can be overridden in Ruby by dropping the set and using assignment. This means the following three statements are equivalent:

widget.setMinimumSize(50) widget.minimumSize = 50 # same widget.minimum_size = 50 # same


Benefits

  • Available on MS Windows, Mac, and GNU/Linux (under commercial license)
  • Has a full-featured embeddable GUI
  • Offers reliable commercial support


Drawbacks

  • Even though a gem is available for the Windows installation. only source code is available for other platforms.
  • Costly preventing large scale adoption.
  • Because Qt is a C++ toolkit, some idioms are used in the toolkit that are necessary due to constraints in the language.


More information about QtRuby and its usage can be obtained from [17].

WxRuby2

WxRuby is an open source GUI toolkit for Ruby programming language. It allows creating cross platform desktop applications. It makes use of the C++ WxWidgetswxWidgets GUI framework. WxWidgets is an open source cross platform library in C++ that aids in creating application for Windows, OS X, Linux and UNIX on 32-bit and 64-bit architectures. It binds languages like python, perl, ruby etc. It has several advantages over other ruby GUI toolkits. Being cross- platform , it has many advanced features with native look and feel. End users do not have to adjust to foreign interface. It is used by many users and actively developed with Unicode support

Sample Hello World Program using WxRuby2

 require 'wx'

  class MyApp < Wx::App
    def on_init
      @frame = Wx::Frame.new( nil, -1, "Hello World" )
      @frame.show
    end
  end

  app = MyApp.new
  app.main_loop

The class inherits from the app class of WXruby. The on_init method of a Wx::App class is run before the main loop of that application is entered. parent widget is the first parameter of the constructor. The second parameter of widget constructors is an id field. The third parameter of the Wx::Frame constructor is the text to display in the title .

'wx' module is required to load WxRuby library. The class containing all the WxRuby applications must be inherited from the Wx::App class. The on_init method is used to create any widget. The widget Frame here has three arguments (parent class, unique ID number, text to be displayed). The 'show' method has to be called for the Frame to be displayed [6].

Getting and Setting Options

C++ and Java conventions are used for naming the methods for getting and setting properties using wxWidgets API. For example, In C++ style,to get and set the size of a widget, the methods are named :

 widget.get_size
 widget.set_size(new_size)

In Ruby, methods are named simply after the property. Therefore, in wxRuby, the following are valid alternatives to the above: [19]

 widget.size
 widget.size = new_size

Creating Menu

Wx::MenuBar object holds the menu and the Wx::Menu objects. Every menu option has a unique ID number assigned to it and its respective callback function is called every time that option is selected by the user.

Types of ID are -

Wx::ID_ANY -> This ID is used for dummy options when ID is not of significance. Wx::ID_EXIT -> Allows user to perform any operation on the Exit option. Wx::ID_LOWEST -> If any ID is lesser than the LOWEST, it creates no conflict with internal ID. Wx::ID_HIGHEST -> If any ID is higher than the HIGHEST, it creates no conflict with internal ID.

'append' - It adds a menu item to the menu bar. Usually takes three arguments - ID, text to be displayed, keyboard shortcut.

Example - [7]

Creating a Help Menu -

 help = Wx::Menu.new
 help.append( Wx::ID_ABOUT, "&About...\tF1", "Show about dialog" )
 menu. append( help, "&Help" )

Benefits

  • Stable and complete GUI toolkit
  • Consistent look and feel because of the usage of native widgets
  • Good support for all platforms
  • WxWidgets has bindings for python, perl, java, lua, eiffel, C# (.NET), basic and ruby

Drawbacks

  • Even though it has bindings for other languages, the API is mostly C++ oriented
  • WxWidgets tries to support a very expansive feature set, and as a result, some lesser-used components of the toolkit are not as stable/reliable as commonly used components are
  • It does not provide binaries for any system.
  • It has to be compiled manually


More information and example programs can be obtained from the tutorial [9]

Shoes

It is not designed for serious, large-scale GUI applications. Shoes applications usually tend to be small, useful and clever programs, which can be used for online or offline purposes. The application is very simple with a shallow learning curve. It is the quickest way to create a useful GUI , and it is intuitive to boot.

Sample Hello World Program using Shoes

 Shoes.app :width => 250, :height => 100 do
    para "Hello World!"
  end
 

The Shoes.app is the method which encapsulates the entire application and it takes width and height, in pixels, as parameters. Inside this method, any options can be set. Here, 'para' is a text container used to display the text "Hello World". 'para' can also take multiple arguments. Formatting is possible by inserting the format operation even inside the 'para'. It is also possible to include other text containers such as 'title', 'subtitle', 'tagline', 'caption' etc [10].


Stack and Flow

Shoes implement what are called 'stack' and 'flow'. Stack, as the name suggests, is used to arrange the GUI tools vertically on top of each other and flow does the same thing, horizontally. It is possible to assign the width for flow. When the limit exceeds, i.e., during overflow, stack creates a scroll bar to move down but flow does not create one to move across. It is also possible to create a Flow of Stacks and a Stack of Flows. The width and height are then defined in terms of % of the portion each flow/stack will take up horizontally.

Example -

 Shoes.app :width => 400, :height => 140 do
   flow :width => 250 do
   button "Button 1"
   button "Button 2"
   button "Button 3"
 end


Replace 'flow' by 'stack' to get the stack of buttons. By default, the arrangement of the tools is 'flow'[11]

Images can be displayed, resized, set as background using 'stack' and 'flow'. It is also possible to provide the URL and the corresponding image is placed in the window.

Example - [12]

 stack do
   image 'lilies.jpg'
   image 'lilies.jpg', :width => '150%'
   'background 'background.jpg # This has to be provided before all other statements. Otherwise, it overwrites them.
 end


Benefits

  • Good graphics
  • Simple interface
  • Control at a lower level

Drawbacks

  • Rough around the edges since it attempts to support so many platforms.
  • Lacks many of the more robust widgets common in other toolkit

More information and examples about using Shoes GUI Toolkit for Ruby can be found at [13]

Other Ruby GUI toolkits

GTK - Stable, Well Documented, used for Gnome problems. Requires hefty set of run time libraries.

FLTK - Ruby/FLTK is a Ruby binding for FLTK. Very fast and lightweight GUI toolkit. Can produce smallest binaries of all free toolkits here. But it is outdated and has unmaintained UTF8 patch and unicode patch.

Ruby-Cocoa bridge - This is an open source project that produces web applications with MAC look and feel by combining features of Ruby and objective C programming languages. But this is not widely used because RubyCocoa applications are very slow due to the added overhead of object conversion.

Conclusion

Ruby is a multi-paradigm programming language. It not only supports web application programming, but is a good programming language to write cross platform GUI applications. There are lot of GUI toolkit supported by Ruby from which one can choose to develop their web/desktop application. TkRuby is one of the old cross platform GUI toolkit. WxRuby is a very stable toolkit with a good selection of widgets. QtRuby being a multiplatform toolkit provides interface for Mac, Windows and Unix Operating systems. Fxruby incorporates the functionality of a featureful, highly optimized C++ toolkit. Shoes is a simplified GUI toolkit that creates native applications with a Web feel. These toolkits have their own advantages and disadvantages. It is good to experiment with several GUI toolkits and then choose the one that looks like the best fit for what is trying to be accomplished.

References

  • Dave Thomas, with Chad Fowler and Andy Hunt Programing Ruby, the Pragmatic Programmers, LLC, 2005

External Links

[1] Hello World Window using Tk

[2] Hello World Label in Tk

[3] Dynamic getter and setter in Tk

[4] CallBack

[5] Programming in Ruby Tutorial

[6] Hello World Program using WxRuby

[7] Creating Menu using WxRuby

[8] Adding Status Bar using WxRuby

[9] WxRuby tutorial

[10] Hello World Program using Shoes

[11] Stack and Flow using Shoes

[12] Creating Images and Background using Shoes

[13] Shoes Tutorial

[14] ruby GUI toolkit

[15] Hello World program using FxRuby

[16] Hello World program using QtRuby

[17] QtRuby Tutorial

[18] FoxRuby Documentation Tutorial

[19] Wxruby Overview