用 Ruby Qt 绘图
在 Ruby Qt 编程教程的这一部分中,我们将进行绘图。
我们什么时候需要油漆? 在某些情况下,当我们需要从头开始创建小部件时。 在这种情况下,我们需要绘图。 或者我们想创建图表,特殊装饰,效果或小部件增强。
当我们在 Qt 库中进行绘图时,Painter
类将发挥作用。 绘图事件通过paintEvent
方法接收。 若要进行自定义绘图,我们必须重新实现此方法。
图案
在 Qt 中,我们可以使用各种图案来填充形状的内部。
#!/usr/bin/ruby
# ZetCode Ruby Qt tutorial
#
# This program draws nine rectangles.
# The interiors are filled with
# different built-in patterns.
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'Qt'
class QtApp < Qt::Widget
def initialize
super
setWindowTitle "Patterns"
resize 350, 280
move 300, 300
show
end
def paintEvent event
painter = Qt::Painter.new self
drawPatterns painter
painter.end
end
def drawPatterns painter
painter.setPen Qt::NoPen
painter.setBrush Qt::HorPattern
painter.drawRect 10, 15, 90, 60
painter.setBrush Qt::VerPattern
painter.drawRect 130, 15, 90, 60
painter.setBrush Qt::CrossPattern
painter.drawRect 250, 15, 90, 60
painter.setBrush Qt::Dense7Pattern
painter.drawRect 10, 105, 90, 60
painter.setBrush Qt::Dense6Pattern
painter.drawRect 130, 105, 90, 60
painter.setBrush Qt::Dense5Pattern
painter.drawRect 250, 105, 90, 60
painter.setBrush Qt::BDiagPattern
painter.drawRect 10, 195, 90, 60
painter.setBrush Qt::FDiagPattern
painter.drawRect 130, 195, 90, 60
painter.setBrush Qt::DiagCrossPattern
painter.drawRect 250, 195, 90, 60
end
end
app = Qt::Application.new ARGV
QtApp.new
app.exec
在代码示例中,我们将绘制九个矩形,并用不同的画笔图案填充它们。
def paintEvent event
painter = Qt::Painter.new self
drawPatterns painter
painter.end
end
当需要重绘窗口区域时,将调用paintEvent
方法。 当我们调整窗口大小,最大化或最小化窗口时,就会发生这种情况。在此方法中,我们创建了Painter
对象。 该对象用于在 Qt 中进行所有绘制。 绘图本身被委托给drawPatterns
方法。
painter.setPen Qt::NoPen
笔对象用于绘制形状的轮廓。 在我们的示例中,我们将不使用笔。
painter.setBrush Qt::HorPattern
我们将水平图案设置为画笔。
painter.drawRect 10, 15, 90, 60
我们用当前的笔和画笔绘制一个矩形。 该方法的前两个参数是 x,y 坐标。 最后两个参数是矩形的宽度和高度。
painter.end
end
方法完成绘制。 释放绘图时使用的所有资源。
图:图案
形状
Qt 绘图 API 可以绘制各种形状。 以下编程代码示例将显示其中的一些。
#!/usr/bin/ruby
# ZetCode Ruby Qt tutorial
#
# This program draws basic shapes
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'Qt'
class QtApp < Qt::Widget
def initialize
super
setWindowTitle "Basic shapes"
resize 350, 280
move 300, 300
show
end
def paintEvent event
painter = Qt::Painter.new self
drawShapes painter
painter.end
end
def drawShapes painter
painter.setRenderHint Qt::Painter::Antialiasing
painter.setPen Qt::Color.new 150, 150, 150
painter.setBrush Qt::Brush.new Qt::Color.new 150, 150, 150
path1 = Qt::PainterPath.new
path1.moveTo 5, 5
path1.cubicTo 40, 5, 50, 50, 99, 99
path1.cubicTo 5, 99, 50, 50, 5, 5
painter.drawPath path1
painter.drawPie 130, 20, 90, 60, 30*16, 120*16
painter.drawChord 240, 30, 90, 60, 0, 16*180
painter.drawRoundRect 20, 120, 80, 50
points = []
points.push Qt::Point.new 130, 140
points.push Qt::Point.new 180, 170
points.push Qt::Point.new 180, 140
points.push Qt::Point.new 220, 110
points.push Qt::Point.new 140, 100
polygon = Qt::Polygon.new points
painter.drawPolygon polygon
painter.drawRect 250, 110, 60, 60
baseline = Qt::PointF.new 20, 250
font = Qt::Font.new "Georgia", 55
path2 = Qt::PainterPath.new
path2.addText baseline, font, "Q"
painter.drawPath path2
painter.drawEllipse 140, 200, 60, 60
painter.drawEllipse 240, 200, 90, 60
end
end
app = Qt::Application.new ARGV
QtApp.new
app.exec
在此代码示例中,我们在窗口上绘制了九种不同的形状。 复杂路径,饼图,和弦,圆角矩形,多边形,矩形,基于字符的形状,圆形和椭圆形。
painter.setRenderHint Qt::Painter::Antialiasing
我们在示例中使用抗锯齿。 抗锯齿形状看起来更好,但是绘制它们需要更多时间。
painter.setPen Qt::Color.new 150, 150, 150
painter.setBrush Qt::Brush.new Qt::Color.new 150, 150, 150
我们使用深灰色的笔和画笔绘制形状。
path1 = Qt::PainterPath.new
path1.moveTo 5, 5
path1.cubicTo 40, 5, 50, 50, 99, 99
path1.cubicTo 5, 99, 50, 50, 5, 5
painter.drawPath path1
使用PainterPath
对象创建第一个复杂形状。 PainterPath
类为绘图操作提供了一个容器。 画家路径是由许多图形构造块(例如矩形,椭圆形,直线和曲线)组成的对象。
painter.drawPie 130, 20, 90, 60, 30*16, 120*16
painter.drawChord 240, 30, 90, 60, 0, 16*180
painter.drawRoundRect 20, 120, 80, 50
这三条线绘制了一个饼图,一个和弦和一个圆角矩形。
points = []
points.push Qt::Point.new 130, 140
points.push Qt::Point.new 180, 170
points.push Qt::Point.new 180, 140
points.push Qt::Point.new 220, 110
points.push Qt::Point.new 140, 100
polygon = Qt::Polygon.new points
painter.drawPolygon polygon
我们使用五个点的数组来创建多边形。
baseline = Qt::PointF.new 20, 250
font = Qt::Font.new "Georgia", 55
path2 = Qt::PainterPath.new
path2.addText baseline, font, "Q"
painter.drawPath path2
这些线创建基于字符的形状。
painter.drawEllipse 140, 200, 60, 60
painter.drawEllipse 240, 200, 90, 60
这两条线分别创建一个圆和一个椭圆。
图:形状
透明矩形
透明度是能够透视材料的质量。 了解透明度的最简单方法是想象一块玻璃或水。 从技术上讲,光线可以穿过玻璃,这样我们就可以看到玻璃后面的物体。
在计算机图形学中,我们可以使用 alpha 合成实现透明效果。 Alpha 合成是将图像与背景组合以创建部分透明外观的过程。 合成过程使用 Alpha 通道。 (wikipedia.org,answers.com)
#!/usr/bin/ruby
# ZetCode Ruby Qt tutorial
#
# This program draws ten
# rectangles with different
# levels of transparency.
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'Qt'
class QtApp < Qt::Widget
def initialize
super
setWindowTitle "Transparent rectangles"
resize 590, 90
move 300, 300
show
end
def paintEvent event
painter = Qt::Painter.new self
drawRectangles painter
painter.end
end
def drawRectangles painter
painter.setPen Qt::NoPen
for i in 1..10
painter.setBrush Qt::Brush.new Qt::Color.new 0, 0, 255, i*25
painter.drawRect 50*i, 20, 40, 40
end
end
end
app = Qt::Application.new ARGV
QtApp.new
app.exec
在示例中,我们将绘制十个具有不同透明度级别的矩形。
painter.setPen Qt::NoPen
我们不用笔。
for i in 1..10
painter.setBrush Qt::Brush.new Qt::Color.new 0, 0, 255, i*25
painter.drawRect 50*i, 20, 40, 40
end
Color
对象的最后一个参数是 alpha 透明度值。
图:透明矩形
甜甜圈形状
在下面的示例中,我们通过旋转一堆椭圆来创建复杂的形状。
#!/usr/bin/ruby
# ZetCode Ruby Qt tutorial
#
# This program draws a donut
# shape
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'Qt'
class QtApp < Qt::Widget
def initialize
super
setWindowTitle "Donut"
resize 350, 280
move 300, 300
show
end
def paintEvent event
painter = Qt::Painter.new self
drawDonut painter
painter.end
end
def drawDonut painter
painter.setRenderHint Qt::Painter::Antialiasing
color = Qt::Color.new
color.setNamedColor "#333333"
pen = Qt::Pen.new color
pen.setWidth 1
painter.setPen pen
w = width
h = height
painter.translate Qt::Point.new w/2, h/2
72.times do
painter.drawEllipse -125, -40, 250, 80
painter.rotate 5.0
end
end
end
app = Qt::Application.new ARGV
QtApp.new
app.exec
在此示例中,我们创建一个甜甜圈。 形状类似于曲奇,因此得名“甜甜圈”。
color = Qt::Color.new
color.setNamedColor "#333333"
我们可以使用十六进制表示法来创建颜色对象。
w = width
h = height
在这里,我们确定窗口的宽度和高度。
painter.translate Qt::Point.new w/2, h/2
我们将坐标系移到窗口的中间。 这样,我们使绘图在数学上更容易。
72.times do
painter.drawEllipse -125, -40, 250, 80
painter.rotate 5.0
end
我们绘制一个椭圆对象 72 次。 每次,我们将椭圆旋转 5 度。 这将创建我们的甜甜圈形状。
图:多纳圈
绘制文字
在最后一个示例中,我们将在窗口上绘制文本。
#!/usr/bin/ruby
# ZetCode Ruby Qt tutorial
#
# This program draws text
# on the window
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'Qt'
class QtApp < Qt::Widget
def initialize
super
setWindowTitle "Soulmate"
resize 370, 240
move 300, 300
show
end
def paintEvent event
painter = Qt::Painter.new self
drawText painter
painter.end
end
def drawText painter
painter.setBrush Qt::Brush.new Qt::Color.new 25, 25, 25
painter.setFont Qt::Font.new "Purisa", 10
painter.drawText Qt::Point.new(20, 30),
"Most relationships seem so transitory"
painter.drawText Qt::Point.new(20, 60),
"They're good but not the permanent one"
painter.drawText Qt::Point.new(20, 120),
"Who doesn't long for someone to hold"
painter.drawText Qt::Point.new(20, 150),
"Who knows how to love without being told"
painter.drawText Qt::Point.new(20, 180),
"Somebody tell me why I'm on my own"
painter.drawText Qt::Point.new(20, 210),
"If there's a soulmate for everyone"
end
end
app = Qt::Application.new ARGV
QtApp.new
app.exec
我们在窗口上画一首歌歌词。
painter.setFont Qt::Font.new "Purisa", 10
我们为文本设置了 Purisa 字体。
painter.drawText Qt::Point.new(20, 30),
"Most relationships seem so transitory"
drawText
方法用于绘制文本。
图:绘制文本
在 Ruby Qt 编程教程的这一部分中,我们做了一些绘图。