The basic method of GTK Ruby GUI programming with the help of RubyGnome2 Library _ruby Special Topic

Source: Internet
Author: User
Tags gtk object model

Objective
As the RubyGnome2 library becomes more sophisticated and ruby1.9 performance improves, writing GUI programs with Ruby gradually turns from my hobby to an important part of my job.

Writing a program in Ruby is really fun, and it allows you to quickly get your ideas in a graceful way. A gem described in this article is an example of a very interesting feature with very little code that makes it easy to write Ruby GUI programs.

RubyGnome2 Introduction

Although I have introduced RubyGnome2 many times before, I would like to recommend RubyGnome2 again, which is the first choice to write GUI programs using Ruby.

RubyGnome2 is a ruby extension of the GTK + library. It encapsulates the object model of GTK + carefully in ruby fashion, preserving the GTK + API naming and meaning, so GTK + documents are also applicable to RubyGnome2---although I think RubyGnome2 's documentation has been pretty good, There are few places to go to learn about GTK documents.

Although the GTK itself is written by C, it has a complete set of carefully designed object systems that allow its GUI components to be very flexible and free to combine 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. A feature that looks very simple on the surface in many cases is a few bends in the GTK. For example, to set the font of a label, to be implemented through Pango, Pango takes over all of GTK's font rendering transactions .... This "more than a few bends" situation many, it does make the writing GTK program is not so straightforward. But in exchange for the entire GTK system has become very flexible, with less cost to achieve a powerful function, across the platform, skin, internationalization above all have a good performance.

RubyGnome2 inherits all the features of GTK, including advantages and disadvantages.

GUI Layout
The layout of the GTK program is flexible and there are many kinds of containers to choose from. At the time of layout, most of them recommend relative position rather than absolute position, so GUI program can better adapt to different resolution screen, also benefit the fine tune of specific style to UI.
The most common container is "box", which includes "Horizontal box" and "Vertical box". By putting visual UI components into "boxes", different "boxes" can be stacked together to build a target layout.

Theoretically, a box can be used to build any relative position layout, but for the sake of aspect, GTK also provides a more advanced container like table.

Box models are difficult to adapt to many people who have just started GTK programming, using visual layout tools such as Glade, and beginners are often bothered by box models. The visual layout is best at the fixed position layout. For relative position layout, many times it is quicker and easier to build interfaces with code than to use Glade.

But there's a significant downside to building a code interface, which is "not intuitive," which is that it's hard to see the UI layout from the code, which can cause later maintenance and change problems.

Some GUI libraries, such as Shose, describe the UI with builder-style code, allowing the UI layout to be graphically represented by code such as the following example 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, and for Web interface designers who are familiar with HTML, a visual editor is not much needed.


RubyGnome2 does not provide us with the layout of the builder way, so the UI code is written like this:


Class Mywin < Gtk::window 
 def initialize 
  super 
  VBox = gtk::vbox.new btn_mice 
  = Gtk::button.new ' Mice ' 
  vbox.pack_start btn_mice 
  btn_eagles = Gtk::button.new ' Eagles ' 
  vbox.pack_start btn_eagles 
  -btn _quail = Gtk::button.new ' quail ' 
  vbox.pack_start btn_quail 
  add vbox 
 end 
 



It's hard to see the UI layout from the code above.

If you also build a builder-style layout for RubyGnome2, the code becomes:


Class Mywin < Gtk::window 
 
 def initialize 
  super 
  add my_layout 
 end 
 
 def my_layout 
  VBox Do 
   button ' Mice ' button ' 
   Eagles ' 
   button ' quail ' 
 
 


&NBSP
 
Well, this code is about the same as Shose, which gives you a glance at the UI layout from your code.
&NBSP
One of the features of the gtksimplelayout described in this article is to provide a builder-style layout for RubyGnome2.
 
gtksimplelayout layout
This simple layout originally had only 200 lines of code that I used to copy directly to the project. Then gradually added some features, feel that it became more useful, and then published to the GitHub to generate gems to facilitate the use of interested people.
 
Source:git://github.com/rickyzheng/gtksimplelayout.git
or:
Gem source-a http:// gems.github.com && gem install rickyzheng-gtksimplelayout
 
The following are the main feature descriptions and simple examples.
 
provide builder style layout
as described in the previous example, Gtksimplelayout brings builder-style layout for RubyGnome2. Just need to extend gtksimplelayout::base for the class of the layout, 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 def my_layout 
  Hbox do 
    label ' Hello, ' 
    button ' world! ' 
   End 
 End 
 



MyWin.new.show_all
Gtk.main


As can be seen from the example above, Gtksimplelayout does not change the main frame of the RubyGnome2 program, it is just an extension.


Property settings
when you place a UI component, you often need to set the initial properties, or you want to specify layout parameters. Gtksimplelayout use hash to pass these properties and parameters, for example:


VBox do 
 button ' sensitive = False ',: Sensitive => False # Initially disable status 
 button ' Expand space ': Layout => [ True, True] # Specify this button to fill the remaining space end 
 





In the example above, the first button has an initial state of disable. ": Sensitive => false" This parameter is eventually converted to a property setting: Gtk::button#sensitive=false, as for Gtk::button there are those properties that can be set, see RubyGnome2 API document or GTK document. Gtksimplelayout here is simply a conversion of a simple parameter.

": Layout => [True, True]" for the second button is somewhat special. The ": Layout" parameter is a gtksimplelayout retention parameter that is converted to an argument when the UI is put into a container. In this case, the container is VBox (Gtk::vbox), and the default join method is Gtk::vbox#pack_start, in which case [true, true] is eventually passed to Pack_start, So the method that the button calls when it is added to the VBox and the argument is: "Gtk::vbox#pack_start (Button, True, True)".

Therefore, to use gtksimplelayout, you should first familiarize yourself with the various components of the RubyGnome2, the usage of the container, and the parameters. When you are familiar with the RubyGnome2, it will be very easy to use gtksimplelayout.

Batch property settings
in the UI layout, you often encounter situations where you want to set the same properties for a set of UI components, such as:


Hbox do 
  button ' C ',: Layout => [False, False, 5] 
  button ' D ',: Layout => [False, False, 5] 
  button ' E ',: l Ayout => [False, False, 5] End 
 





This time, you can use "with_attr" to simplify:


Hbox do 
 with_attr:layout => [False, False, 5] does 
  button ' C ' 
  button ' D ' 
  button ' E ' 
end  



Special Containers
Some containers have special requirements for the placement of the child components, such as gtk::hpaned, the left child window to be added with GTK::HPANED#ADD1 (), the right side of the GTK::HPANED#ADD2 (). For such containers, gtksimplelayout should be treated in a special way, taking hpaned as an example:


hpaned do 
 Area_first do frame ' the ' the ' the ' the ' the ' the ' the ' 
 second area 
  ' 
 end End 





Containers that require special treatment are:
hpaned/vpaned: Use Area_first and Area_second to add child windows.
Table: Fills the grid with grid.
Nodebook: Add a child page with a page.

Identifying UI Components
gtksimplelayout with ": ID =>??" This parameter identifies the UI component, for example:


Hbox do 
 button ' I ',: ID =>: Btn_first 
 button ' second ',: ID =>: Btn_second 
End 



The UI component can then be obtained using the component () function:


My_first_button = Component (: btn_first) 
My_second_button = component (: Btn_second) 
 
... 
My_first_button.signal_connect (' clicked ') do 
 puts "the" "" "" The "" "" "" 
 
Connect (' clicked ') do 
 puts "second button clicked" 




If it's too much trouble, Gtksimplelayout also provides expose_components () for automatically adding all identified components as instance read properties (getter):



Expose_components () # will automatically add both the Btn_first and Btn_second read properties (getter).


... 
Btn_first.signal_connect (' clicked ') do puts "the" "" The "" The "" "" " 
 ," clicked "End 
 
btn_second.signal_connect Clicked ') do 
 puts "second button clicked" 
end 




Automatic Event Response mapping
If you don't want to explicitly call Signal_connect to register event trouble, then Gtksimplelayout provides you with the function of automatic event response mapping:


 require ' gtk2 ' Require ' Simple_layout ' class Mywin < Gtk::window include simple 
  Layout::base def Initialize super add My_layout register_auto_events () # Register automatic Event response mapping End def my_layout Hbox do button "A",: Btn_first button "Second": Btn_second End # event response Function Def Btn_first_on_click 
 Ed (*_) puts "the" "The" "The" "The" "The" "The" "The" "Clicked" End # Event response function Def btn_second_on_clicked (*_) puts End # Exit Event response Function Def self_on_destroy (*_) gtk.main_quit end
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 grouping
Sometimes you want to group UI components so that you can control the same set of UI components, such as enabling or banning the entire group. Gtksimplelayout allows you to specify the UI group in the layout. The UI grouping rules for the
Gtksimplelayout are as follows:
By default, named Containers (that is, incoming: ID parameters) automatically set up a group for the child components of which they belong, and the group name is the container.
If the container is passed in: gid=>?? parameter, the group is established with this name as the owning child component. The
allows multiple containers to have the same name for the GID, in which case the child components belong to the same group. The
Group can be used to group the UI explicitly, and the group can be considered a virtual container. The
uses Component_children (group_name) to get the UI group.
&NBSP
Because the example of UI grouping is long, see the examples/group.rb file
 
 
UI and Logical code separation
because Gtksimplelayout potentially forces users to detach interface code and logical processing (or event response) code, the hierarchy of the entire program becomes clearer. For many of the interface components of the program, can be very convenient zoning for layout, because the result of the layout or container, the container can be put into other containers into a more complex interface.
 
Because Gtksimplelayout does not change the RUBYGNOME2 program structure, you can choose to use gtksimplelayout in part or all of your program. Although the examples provided in this article are static layouts, because Gtksimplelayout is a stored code building UI, you can simply pass in the variables in the layout, dynamically layout and dynamically generate the UI, while still maintaining the "visualization" of the UI code.
 
 
Interested people can look at the Gtksimplelayout implementation code, but 300 lines, that's the charm of Ruby.
 
Finally, put a code example in the interface section of a calculator, can you see the UI layout from the code?


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.