Using the RubyGnome2 library for the basic method of Ruby GUI programming under GTK,

Source: Internet
Author: User

Using the RubyGnome2 library for the basic method of Ruby GUI programming under GTK,

Preface
As the RubyGnome2 library becomes more and more perfect and ruby1.9 performance is improved, writing GUI programs in Ruby has gradually changed from my hobbies to an important part of my work.
 
Writing a program in Ruby is really fun. It allows you to quickly implement your ideas in an elegant way. The gem introduced in this article is an example. It uses very little code to implement interesting functions, making it easy and pleasant to compile Ruby GUI programs.
 
RubyGnome2 Introduction
 
Although I have introduced RubyGnome2 many times before, I still want to recommend RubyGnome2 again, which is the first choice for compiling GUI programs using Ruby.
 
RubyGnome2 is a ruby extension of the GTK + Library. It carefully encapsulates the GTK + Object Model in Ruby mode and retains the GTK + API naming method and meaning, therefore, the GTK + documentation is also applicable to RubyGnome2-although I think the document of RubyGnome2 has done a very good job, there are not many places to learn from the GTK documentation.
 
Although GTK is compiled by C itself, it has a complete set of well-designed object systems, allowing its GUI components to be flexibly and freely combined to achieve complex, powerful interfaces.
 
Since GTK attaches great importance to the flexibility of its object system, it is not easy to start using GTK programming. Most of the time, on the surface, it looks very simple. In GTK, it takes several turns to achieve this. For example, to set a label font, you must use Pango. Pango takes over all the font rendering transactions of GTK .... this kind of "more turns around a few turns" makes it really less straightforward to write GTK programs. But in exchange, the entire GTK system becomes very flexible and provides powerful functions at a low cost. It has a good performance in cross-platform, skin-changing, and internationalization.
 
RubyGnome2 inherits all the features of GTK, including its advantages and disadvantages.
 
GUI Layout
The layout of the GTK program is flexible and there are many containers to choose from. In the layout, most of them are recommended relative positions rather than absolute positions, so that GUI programs can better adapt to screens with different resolutions, and also facilitate the fine tune of the UI in specific styles.
The most common containers are "Boxes", including "Horizontal boxes" and "vertical boxes ". Put visual UI elements into a "box", and different "Boxes" are combined and stacked to build a target layout.
 
Theoretically, a box can be used to build any relative layout, but GTK also provides a more advanced container like table.
 
The box model is difficult for many people who have just begun GTK programming, that is, they use visual layout tools such as Glade, and beginners are often troubled by the box model. The visual la er is best at fixed-position la S. For relative location layout, it is more convenient to use code to build the interface than to use Glade.
 
However, building interfaces with code has a notable drawback, that is, "not intuitive", that is, it is difficult to see the UI layout from the code, which will cause trouble for later maintenance and changes.
 
Some GUI Libraries such as Shose use builder-style code to describe the UI, so that the UI layout can be reflected in the Code image. The following example is from shooose.net:
 

Shoes.app { 
 stack(:margin => 4) { 
  button "Mice" 
  button "Eagles" 
  button "Quail" 
 } 
} 

 
 
In this way, we can see the UI layout from the code.
 
Builder-style code is similar to HTML. For web interface designers familiar with HTML, visual editor is not necessary.
 
 
RubyGnome2 does not provide us with a builder layout, so the UI code is written like:
 

Shoes.app { 
 stack(:margin => 4) { 
  button "Mice" 
  button "Eagles" 
  button "Quail" 
 } 
} 


From the code above, it is difficult to see the UI layout at once.
 
If you also build a builder-style layout for RubyGnome2, the code will become:
 

class MyWin < Gtk::Window 
 
 def initialize 
  super 
  add my_layout 
 end 
 
 def my_layout 
  vbox do 
   button 'Mice' 
   button 'Eagles' 
   button 'Quail' 
  end 
 end 
 
end 

 
 
Well, this code is similar to Shose. You can see the UI layout from the code.
 
One of the functions of GtkSimpleLayout described in this article is to provide a builder layout for RubyGnome2.
 
GtkSimpleLayout
This simple la er originally had less than 200 lines of code, which I often directly copied to the project for use. Later, I gradually added some features and thought they became more useful. So I released them to github to generate a gem for users who are interested in it.
 
Source: git: // github.com/rickyzheng/GtkSimpleLayout.git
Or:
Gem source-a http://gems.github.com & gem install rickyzheng-GtkSimpleLayout
 
The following describes the main functions and simple examples.
 
Provides Builder Layout
As described in the above example, GtkSimpleLayout provides the builder layout function for RubyGnome2. You only need to extend GtkSimpleLayout: Base for the layout class. A complete example:
 

require 'gtk2' 
require 'simple_layout' 
 
class MyWin < Gtk::Window 
 include SimpleLayout::Base 
 def initialize 
  super 
  add my_layout 
  signal_connect('destroy') do 
   Gtk.main_quit 
  end 
 end 
 
 def my_layout 
  hbox do 
    label 'Hello, ' 
    button 'World !' 
   end 
 end 
end 


MyWin. new. show_all
Gtk. main
 
 
As shown in the preceding example, GtkSimpleLayout does not change the main framework of the RubyGnome2 program. It is just an extension.
 
 
Attribute settings
When placing the UI component, you often need to set the initial attribute or specify the layout parameters. GtkSimpleLayout uses Hash to pass these attributes and parameters, for example:
 

vbox do
  button 'sensitive = false',: sensitive => false # Initially disabled
  button 'expand space',: layout => [true, true] # specify that this button fills the remaining space
end


In the preceding example, the initial status of the first button is disable. ": Sensitive => false" is converted to the Property setting: Gtk: Button # sensitive = false. For Gtk: Button, you can set the attributes, see the RubyGnome2 API document or GTK document. GtkSimpleLayout is just a simple parameter conversion here.
 
The ": layout => [true, true]" of the second button is special. ": Layout" is the reserved parameter of GtkSimpleLayout, which is converted to the parameter when the UI is put into the container. In this example, the container is vbox (Gtk: VBox), and the default addition method is Gtk: VBox # pack_start. In this example, [true, true] will be passed to pack_start. Therefore, when this button is added to vbox, the call method and parameter are: "Gtk: VBox # pack_start (button, true, true) ".
 
Therefore, to use GtkSimpleLayout, you must first familiarize yourself with the components of RubyGnome2, container usage, and parameters. When you are familiar with RubyGnome2, using GtkSimpleLayout will be very simple.
 
Batch attribute settings
During UI layout, you often encounter the situation where you need to set the same attributes for a group of UI elements, such:

hbox do 
  button 'C', :layout => [false, false, 5] 
  button 'D', :layout => [false, false, 5] 
  button 'E', :layout => [false, false, 5] 
end 


In this case, you can use "with_attr" to simplify the process:

hbox do 
 with_attr :layout => [false, false, 5] do 
  button 'C' 
  button 'D' 
  button 'E' 
 end 
end  

 
Special container
Some containers have special requirements for sub-components, such as Gtk: HPaned. The left-side sub-window must be added with Gtk: HPaned # add1 (), and the right side should be added with Gtk :: HPaned # add2 (). For such containers, GtkSimpleLayout should be specially treated. Take hpaned as an example:

hpaned do 
 area_first do 
  frame 'first area' 
 end 
 area_second do 
  frame 'second area' 
 end 
end


Containers that require special treatment include:
Hpaned/vpaned: Use area_first and area_second to add subwindows.
Table: Use a grid to fill the grid.
Nodebook: Use page to add subpages.
 
Identify the UI component
Use ": id => ?? "This parameter is identified by the UI component, for example:

hbox do 
 button 'first', :id => :btn_first 
 button 'second', :id => :btn_second 
end 

 
You can use the component () function to obtain the UI component:

my_first_button = component(:btn_first) 
my_second_button = component(:btn_second) 
 
... 
my_first_button.signal_connect('clicked') do 
 puts "first button clicked" 
end 
 
my_second_button.signal_connect('clicked') do 
 puts "second button clicked" 
end 

 
 
If it is too troublesome, GtkSimpleLayout also provides expose_components () to automatically add all identified elements as the instance read attribute (getter ):

Expose_components () # The two read attributes (getter) btn_first and btn_second will be automatically added ).

... 
btn_first.signal_connect('clicked') do 
 puts "first button clicked" 
end 
 
btn_second.signal_connect('clicked') do 
 puts "second button clicked" 
end 

 
 
Automatic Event Response ing
If you explicitly call signal_connect to register events, GtkSimpleLayout provides you with the automatic Event Response ing function:

require 'gtk2'
require 'simple_layout'
 
class MyWin <Gtk :: Window
  include SimpleLayout :: Base
  def initialize
   super
   add my_layout
   register_auto_events () # Register automatic event response mapping
  end
 
  def my_layout
   hbox do
    button "First ',: btn_first
    button "Second",: btn_second
   end
  end
 
  # Event response function
  def btn_first_on_clicked (* _)
   puts "First button clicked"
  end
 
  # Event response function
  def btn_second_on_clicked (* _)
   puts "Second button clicked"
  end
 
  # Exit event response function
  def self_on_destroy (* _)
   Gtk.main_quit
  end
end

 
The last 'self 'refers to the host container.
 
UI group
Sometimes you want to group the UI components so that you can control the UI components in the same group, such as enabling or disabling the entire group. GtkSimpleLayout allows you to specify the UI group during layout.
The UI grouping rules of GtkSimpleLayout are as follows:
By default, the named container (that is, the input: id parameter) automatically creates a group for its child components. The group name is the container name.
If the container is passed in: gid => ?? Parameter.
Multiple containers are allowed with the same gid name. In this case, the sub-components are grouped into the same group.
You can use "group" to explicitly group the UI. A group can be considered as a virtual container.
Use component_children (group_name) to obtain the UI group.
 
The examples of UI grouping are not listed here for a long time. For details, refer to the examples/group. rb file in the source code.
 
 
Separation of UI and logic code
GtkSimpleLayout potentially forces the user to separate the interface code from the logic processing (or Event Response) Code, making the hierarchy of the entire program clearer. For programs with many interface elements, layout can be easily partitioned. Because the result of layout is still a container, this container can be combined into other containers to form a more complex interface.
 
Because GtkSimpleLayout does not change the program structure of RubyGnome2, you can choose to use GtkSimpleLayout in part or all of your programs. Although the examples provided in this article are static la s, because GtkSimpleLayout is used to store code to build the UI, You can input variables during layout for Dynamic Layout and UI generation, the UI code is still visualized ".
 
 
If you are interested, you can look at the Code implemented by GtkSimpleLayout, but there are only 300 lines. This is Ruby's charm.
 
Finally, you can see the UI layout from the code by pasting the code example of a calculator interface?

require 'gtk2' 
require 'simple_layout' 
 
class MyWin < Gtk::Window 
 include SimpleLayout::Base 
 def initialize 
  super 
  add my_layout 
  signal_connect('destroy') do 
   Gtk.main_quit 
  end 
 end 
 
 def my_layout 
  vbox do 
   with_attr :border_width => 3 do 
    hbox do 
     entry :id => :ent_input, :layout => [true, true, 5] 
    end 
    hbox do 
     frame do 
      label 'M', :set_size_request => [20, 20] 
     end 
     hbutton_box do 
      button 'Backspace' 
      button 'CE' 
      button 'C' 
     end 
    end 
    hbox do 
     vbutton_box do 
      button 'MC' 
      button 'MR' 
      button 'MS' 
      button 'M+' 
     end 
     with_attr :layout => [true, true] do 
      number_and_operators_layout 
     end 
    end 
   end 
  end 
 end 
 
 def number_and_operators_layout 
  vbox do 
   [ ['7', '8', '9', '/', 'sqt'], 
    ['4', '5', '6', '*', '%'], 
    ['1', '2', '3', '-', '1/x'], 
    ['0', '+/=', '.', '+', '=']].each do |cols| 
    hbox :layout => [true, true] do 
     cols.each do |txt| 
      button txt, :set_size_request => [20, 20], :layout => [true, true] 
     end 
    end 
   end 
  end 
 end 
 
end 


MyWin. new. show_all
Gtk. main


Enjoy it :-)


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.