在 Ruby Qt 编程教程的这一部分中,我们将创建一个自定义窗口小部件。
工具箱通常仅提供最常见的窗口小部件,例如按钮,文本窗口小部件,滑块等。没有工具箱可以提供所有可能的窗口小部件。 程序员必须自己创建此类小部件。 他们使用工具箱提供的绘图工具来完成此任务。 有两种可能性。 程序员可以修改或增强现有的小部件。 或者,他可以从头开始创建自定义窗口小部件。
刻录小部件
在下一个示例中,我们将创建一个自定义刻录小部件。 可以在 Nero 或 K3B 之类的应用中看到此小部件。 该小部件将从头开始创建。
#!/usr/bin/ruby
# ZetCode Ruby Qt tutorial
# In this program, we create
# a custom widget
#
# @author jan bodnar
# website zetcode.com
# last modified July 2009
require 'Qt'
PANEL_HEIGHT = 30
DISTANCE = 19
LINE_WIDTH = 5
DIVISIONS = 10
FULL_CAPACITY = 700
MAX_CAPACITY = 750
class Burning < Qt::Widget
def initialize(parent)
super(parent)
@num = [ "75", "150", "225", "300",
"375", "450", "525", "600", "675" ]
@redColor = Qt::Color.new 255, 175, 175
@yellowColor = Qt::Color.new 255, 255, 184
@parent = parent
setMinimumHeight PANEL_HEIGHT
end
def paintEvent event
painter = Qt::Painter.new self
drawWidget painter
painter.end
end
def drawWidget painter
w = width.to_f
slid_width = @parent.getCurrentWidth
step = (w / DIVISIONS).round.to_f
till = ((w / MAX_CAPACITY) * slid_width).to_f
full = ((w / MAX_CAPACITY) * FULL_CAPACITY).to_f
if slid_width > FULL_CAPACITY
painter.setPen @yellowColor
painter.setBrush Qt::Brush.new @yellowColor
painter.drawRect Qt::RectF.new 0, 0, full, PANEL_HEIGHT
painter.setPen @redColor
painter.setBrush Qt::Brush.new @redColor
painter.drawRect Qt::RectF.new full+1, 0, till-full, PANEL_HEIGHT
else
if slid_width > 0
painter.setPen @yellowColor
painter.setBrush Qt::Brush.new @yellowColor
painter.drawRect Qt::RectF.new 0, 0, till, PANEL_HEIGHT
end
end
painter.setPen Qt::Color.new 90, 90, 90
painter.setBrush Qt::NoBrush
painter.drawRect 0, 0, w-1, PANEL_HEIGHT-1
newFont = font
newFont.setPointSize 7
painter.setFont newFont
for i in (1..@num.length)
painter.drawLine Qt::LineF.new i*step, 1, i*step, LINE_WIDTH
metrics = Qt::FontMetrics.new newFont
w = metrics.width @num[i-1]
painter.drawText(Qt::PointF.new(i*step-w/2, DISTANCE), @num[i-1])
end
end
end
class QtApp < Qt::Widget
slots 'onChanged(int)'
def initialize
super
setWindowTitle "The Burning Widget"
initUI
resize 370, 200
move 300, 300
show
end
def initUI
@cur_width = 0
@slider = Qt::Slider.new Qt::Horizontal , self
@slider.setMaximum MAX_CAPACITY
@slider.setGeometry 50, 50, 130, 30
connect(@slider, SIGNAL("valueChanged(int)"), self, SLOT("onChanged(int)"))
vbox = Qt::VBoxLayout.new self
hbox = Qt::HBoxLayout.new
vbox.addStretch 1
@widget = Burning.new self
hbox.addWidget @widget, 0
vbox.addLayout hbox
setLayout vbox
end
def onChanged val
@cur_width = val
@widget.repaint
end
def getCurrentWidth
return @cur_width
end
end
app = Qt::Application.new ARGV
QtApp.new
app.exec
在这个文件中,我们创建了刻录小部件。
class Burning < Qt::Widget
自定义窗口小部件基于Widget
小部件。
PANEL_HEIGHT = 30
DISTANCE = 19
LINE_WIDTH = 5
DIVISIONS = 10
FULL_CAPACITY = 700
MAX_CAPACITY = 750
这些是重要的常数。 PANEL_HEIGHT
定义自定义窗口小部件的高度。 DISTANCE
是比例尺上的数字与其父边框顶部之间的距离。 LINE_WIDTH
是垂直线的宽度。 DIVISIONS
是秤的数量。 FULL_CAPACITY
是媒体的最大容量。 达到目标后,就会发生过度刻录。 这通过红色可视化。 MAX_CAPACITY
是介质的最大容量。
@num = [ "75", "150", "225", "300",
"375", "450", "525", "600", "675" ]
我们使用这些数字来构建Burning
小部件的比例。
def paintEvent event
painter = Qt::Painter.new self
drawWidget painter
painter.end
end
自定义窗口小部件的图形委托给drawWidget
方法。
slid_width = @parent.getCurrentWidth
我们使用它来获取当前选定的滑块值。
w = width.to_f
我们得到小部件的宽度。 自定义窗口小部件的宽度是动态的。 用户可以调整大小。
till = ((w / MAX_CAPACITY) * slid_width).to_f
full = ((w / MAX_CAPACITY) * FULL_CAPACITY).to_f
我们使用w
变量进行转换。 在比例尺值和自定义小部件的度量之间。 请注意,我们使用浮点值。 我们在绘图中获得了更高的精度。
painter.setPen @redColor
painter.setBrush Qt::Brush.new @redColor
painter.drawRect Qt::RectF.new full+1, 0, till-full, PANEL_HEIGHT
这三行画出红色矩形,表示过度燃烧。
painter.drawRect 0, 0, w-1, PANEL_HEIGHT-1
这是小部件的外围,即外部矩形。
painter.drawLine Qt::LineF.new i*step, 1, i*step, LINE_WIDTH
在这里,我们画出小的垂直线。
w = metrics.width @num[i-1]
painter.drawText(Qt::PointF.new(i*step-w/2, DISTANCE), @num[i-1])
在这里,我们绘制刻度的数字。 为了精确定位数字,我们必须获得字符串的宽度。
@widget = Burning.new self
hbox.addWidget @widget, 0
我们创建Burning
小部件的实例并将其添加到水平框中。
def onChanged val
@cur_width = val
@widget.repaint
end
当滑块的值更改时,我们将其存储在@cur_width
变量中,然后重新绘制自定义窗口小部件。
def getCurrentWidth
return @cur_width
end
定制小部件调用此方法以获取实际的滑块值。
图:刻录小部件
在 Ruby Qt 教程的这一部分中,我们已经演示了如何创建自定义窗口小部件。