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:-)