[翻译]Ruby GTK教程7——自定义控件

自定义控件

大多数套件通常只提供了最常用的控件,如按钮、文本控件、滑动条等。没有套件可以提供所有可能的控件。程序员必须自己创建这些。这是通过套件提供的绘制工具完成。这有两种可能。程序员可以修改或增强已存在的控件,或者从头开始创建一个自定义控件。


Burning控件


这个例子我们从头开始创建一个控件。这个控件可以在各种媒体烧定应用中看到,如Nero Burning ROM。


custom.rb


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example creates a burning
# custom widget
#
# author: jan bodnar
# website: zetcode.com
# last edited: June 2009


require ‘gtk2’

class Burning < Gtk::DrawingArea

def initialize(parent)
@parent = parent

super()

@num = [ “75”, “150”, “225”, “300”,
“375”, “450”, “525”, “600”, “675” ]

set_size_request 1, 30
signal_connect “expose-event” do
expose
end
end


def expose

cr = window.create_cairo_context
draw_widget cr

end

def draw_widget cr

cr.set_line_width 0.8

cr.select_font_face(“Courier”,
Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL)
cr.set_font_size 11

width = allocation.width

@cur_width = @parent.get_cur_value

step = (width / 10.0).round

till = (width / 750.0) @cur_width
full = (width / 750.0)
700

if @cur_width >= 700

cr.set_source_rgb(1.0, 1.0, 0.72)
cr.rectangle(0, 0, full, 30)
cr.clip
cr.paint
cr.reset_clip

cr.set_source_rgb(1.0, 0.68, 0.68)
cr.rectangle(full, 0, till-full, 30)
cr.clip
cr.paint
cr.reset_clip

else
cr.set_source_rgb 1.0, 1.0, 0.72
cr.rectangle 0, 0, till, 30
cr.clip
cr.paint
cr.reset_clip
end


cr.set_source_rgb(0.35, 0.31, 0.24)

for i in (1..@num.length)
cr.move_to istep, 0
cr.line_to i
step, 5
cr.stroke

te = cr.text_extents @num[i-1]
cr.move_to istep-te.width/2, 15
cr.text_path @num[i-1]
cr.stroke
end
end
end


class RubyApp < Gtk::Window
def initialize
super

set_title “Burning”
signal_connect “destroy” do
Gtk.main_quit
end

set_size_request 350, 200
set_window_position Gtk::Window::POS_CENTER

@cur_value = 0

vbox = Gtk::VBox.new false, 2

scale = Gtk::HScale.new
scale.set_range 0, 750
scale.set_digits 0
scale.set_size_request 160, 35
scale.set_value @cur_value

scale.signal_connect “value-changed” do |w|
on_changed(w)
end

fix = Gtk::Fixed.new
fix.put scale, 50, 50

vbox.pack_start fix

@burning = Burning.new(self)
vbox.pack_start @burning, false, false, 0

add vbox
show_all
end

def on_changed widget

@cur_value = widget.value
@burning.queue_draw
end

def get_cur_value
return @cur_value
end
end

Gtk.init
window = RubyApp.new
Gtk.main

我们将DrawingArea放在窗口的底部,并且手动绘制控件的条目。所有的重要代码放在draw_widget里,通过Burning类的expose方法调用。这个控件生动的显示了媒介的容量和剩余空间。这个控件通过刻度控件来控制。我们自定义控件的最小值为0,最大值为750。如果达到700,我们开始绘制红色。这通常表明超标了。


@num = [ “75”, “150”, “225”, “300”,
“375”, “450”, “525”, “600”, “675” ]

这些数字显示在控件上。他们显示了媒介的容量。


@cur_width = @parent.get_cur_value

通过父控件我们获得刻度控件的值。


till = (width / 750.0)  @cur_width
full = (width / 750.0) 700

我们使用width变量进行刻度值和自定义控件尺寸的转换。注意我们使用了浮点数,得到较大精度的绘制。till参数决定了绘制的总大小,它的值来自刻度控件。它是整个区域的比例。full参数决定了从什么位置开始绘制红色。


cr.set_source_rgb(1.0, 1.0, 0.72)
cr.rectangle(0, 0, full, 30)
cr.clip
cr.paint
cr.reset_clip

绘制黄色矩形直到full点。


te = cr.text_extents @num[i-1]
cr.move_to istep-te.width/2, 15
cr.text_path @num[i-1]
cr.stroke

这些代码绘制了burning控件的数字。我们计算了文本恰当的位置。


def on_changed widget

@cur_value = widget.value
@burning.queue_draw
end

我们获取刻度控件的值保存在cur_value变量中,稍后使用。重绘burning控件。


image

图片:Burning widget


在这一章中,我们创建了一个自定义控件。




原文地址: http://zetcode.com/gui/rubygtk/customwidget/

翻译:龙昌 admin@longchangjin.cn