原文: http://zetcode.com/gui/rubyqt/painting/

在 Ruby Qt 编程教程的这一部分中,我们将进行绘图。

我们什么时候需要油漆? 在某些情况下,当我们需要从头开始创建小部件时。 在这种情况下,我们需要绘图。 或者我们想创建图表,特殊装饰,效果或小部件增强。

当我们在 Qt 库中进行绘图时,Painter类将发挥作用。 绘图事件通过paintEvent方法接收。 若要进行自定义绘图,我们必须重新实现此方法。

图案

在 Qt 中,我们可以使用各种图案来填充形状的内部。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # This program draws nine rectangles.
  5. # The interiors are filled with
  6. # different built-in patterns.
  7. #
  8. # author: jan bodnar
  9. # website: www.zetcode.com
  10. # last modified: June 2009
  11. require 'Qt'
  12. class QtApp < Qt::Widget
  13. def initialize
  14. super
  15. setWindowTitle "Patterns"
  16. resize 350, 280
  17. move 300, 300
  18. show
  19. end
  20. def paintEvent event
  21. painter = Qt::Painter.new self
  22. drawPatterns painter
  23. painter.end
  24. end
  25. def drawPatterns painter
  26. painter.setPen Qt::NoPen
  27. painter.setBrush Qt::HorPattern
  28. painter.drawRect 10, 15, 90, 60
  29. painter.setBrush Qt::VerPattern
  30. painter.drawRect 130, 15, 90, 60
  31. painter.setBrush Qt::CrossPattern
  32. painter.drawRect 250, 15, 90, 60
  33. painter.setBrush Qt::Dense7Pattern
  34. painter.drawRect 10, 105, 90, 60
  35. painter.setBrush Qt::Dense6Pattern
  36. painter.drawRect 130, 105, 90, 60
  37. painter.setBrush Qt::Dense5Pattern
  38. painter.drawRect 250, 105, 90, 60
  39. painter.setBrush Qt::BDiagPattern
  40. painter.drawRect 10, 195, 90, 60
  41. painter.setBrush Qt::FDiagPattern
  42. painter.drawRect 130, 195, 90, 60
  43. painter.setBrush Qt::DiagCrossPattern
  44. painter.drawRect 250, 195, 90, 60
  45. end
  46. end
  47. app = Qt::Application.new ARGV
  48. QtApp.new
  49. app.exec

在代码示例中,我们将绘制九个矩形,并用不同的画笔图案填充它们。

  1. def paintEvent event
  2. painter = Qt::Painter.new self
  3. drawPatterns painter
  4. painter.end
  5. end

当需要重绘窗口区域时,将调用paintEvent方法。 当我们调整窗口大小,最大化或最小化窗口时,就会发生这种情况。在此方法中,我们创建了Painter对象。 该对象用于在 Qt 中进行所有绘制。 绘图本身被委托给drawPatterns方法。

  1. painter.setPen Qt::NoPen

笔对象用于绘制形状的轮廓。 在我们的示例中,我们将不使用笔。

  1. painter.setBrush Qt::HorPattern

我们将水平图案设置为画笔。

  1. painter.drawRect 10, 15, 90, 60

我们用当前的笔和画笔绘制一个矩形。 该方法的前两个参数是 x,y 坐标。 最后两个参数是矩形的宽度和高度。

  1. painter.end

end方法完成绘制。 释放绘图时使用的所有资源。

用 Ruby Qt 绘图 - 图1

图:图案

形状

Qt 绘图 API 可以绘制各种形状。 以下编程代码示例将显示其中的一些。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # This program draws basic shapes
  5. #
  6. # author: jan bodnar
  7. # website: www.zetcode.com
  8. # last modified: June 2009
  9. require 'Qt'
  10. class QtApp < Qt::Widget
  11. def initialize
  12. super
  13. setWindowTitle "Basic shapes"
  14. resize 350, 280
  15. move 300, 300
  16. show
  17. end
  18. def paintEvent event
  19. painter = Qt::Painter.new self
  20. drawShapes painter
  21. painter.end
  22. end
  23. def drawShapes painter
  24. painter.setRenderHint Qt::Painter::Antialiasing
  25. painter.setPen Qt::Color.new 150, 150, 150
  26. painter.setBrush Qt::Brush.new Qt::Color.new 150, 150, 150
  27. path1 = Qt::PainterPath.new
  28. path1.moveTo 5, 5
  29. path1.cubicTo 40, 5, 50, 50, 99, 99
  30. path1.cubicTo 5, 99, 50, 50, 5, 5
  31. painter.drawPath path1
  32. painter.drawPie 130, 20, 90, 60, 30*16, 120*16
  33. painter.drawChord 240, 30, 90, 60, 0, 16*180
  34. painter.drawRoundRect 20, 120, 80, 50
  35. points = []
  36. points.push Qt::Point.new 130, 140
  37. points.push Qt::Point.new 180, 170
  38. points.push Qt::Point.new 180, 140
  39. points.push Qt::Point.new 220, 110
  40. points.push Qt::Point.new 140, 100
  41. polygon = Qt::Polygon.new points
  42. painter.drawPolygon polygon
  43. painter.drawRect 250, 110, 60, 60
  44. baseline = Qt::PointF.new 20, 250
  45. font = Qt::Font.new "Georgia", 55
  46. path2 = Qt::PainterPath.new
  47. path2.addText baseline, font, "Q"
  48. painter.drawPath path2
  49. painter.drawEllipse 140, 200, 60, 60
  50. painter.drawEllipse 240, 200, 90, 60
  51. end
  52. end
  53. app = Qt::Application.new ARGV
  54. QtApp.new
  55. app.exec

在此代码示例中,我们在窗口上绘制了九种不同的形状。 复杂路径,饼图,和弦,圆角矩形,多边形,矩形,基于字符的形状,圆形和椭圆形。

  1. painter.setRenderHint Qt::Painter::Antialiasing

我们在示例中使用抗锯齿。 抗锯齿形状看起来更好,但是绘制它们需要更多时间。

  1. painter.setPen Qt::Color.new 150, 150, 150
  2. painter.setBrush Qt::Brush.new Qt::Color.new 150, 150, 150

我们使用深灰色的笔和画笔绘制形状。

  1. path1 = Qt::PainterPath.new
  2. path1.moveTo 5, 5
  3. path1.cubicTo 40, 5, 50, 50, 99, 99
  4. path1.cubicTo 5, 99, 50, 50, 5, 5
  5. painter.drawPath path1

使用PainterPath对象创建第一个复杂形状。 PainterPath类为绘图操作提供了一个容器。 画家路径是由许多图形构造块(例如矩形,椭圆形,直线和曲线)组成的对象。

  1. painter.drawPie 130, 20, 90, 60, 30*16, 120*16
  2. painter.drawChord 240, 30, 90, 60, 0, 16*180
  3. painter.drawRoundRect 20, 120, 80, 50

这三条线绘制了一个饼图,一个和弦和一个圆角矩形。

  1. points = []
  2. points.push Qt::Point.new 130, 140
  3. points.push Qt::Point.new 180, 170
  4. points.push Qt::Point.new 180, 140
  5. points.push Qt::Point.new 220, 110
  6. points.push Qt::Point.new 140, 100
  7. polygon = Qt::Polygon.new points
  8. painter.drawPolygon polygon

我们使用五个点的数组来创建多边形。

  1. baseline = Qt::PointF.new 20, 250
  2. font = Qt::Font.new "Georgia", 55
  3. path2 = Qt::PainterPath.new
  4. path2.addText baseline, font, "Q"
  5. painter.drawPath path2

这些线创建基于字符的形状。

  1. painter.drawEllipse 140, 200, 60, 60
  2. painter.drawEllipse 240, 200, 90, 60

这两条线分别创建一个圆和一个椭圆。

用 Ruby Qt 绘图 - 图2

图:形状

透明矩形

透明度是能够透视材料的质量。 了解透明度的最简单方法是想象一块玻璃或水。 从技术上讲,光线可以穿过玻璃,这样我们就可以看到玻璃后面的物体。

在计算机图形学中,我们可以使用 alpha 合成实现透明效果。 Alpha 合成是将图像与背景组合以创建部分透明外观的过程。 合成过程使用 Alpha 通道。 (wikipedia.org,answers.com)

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # This program draws ten
  5. # rectangles with different
  6. # levels of transparency.
  7. #
  8. # author: jan bodnar
  9. # website: www.zetcode.com
  10. # last modified: June 2009
  11. require 'Qt'
  12. class QtApp < Qt::Widget
  13. def initialize
  14. super
  15. setWindowTitle "Transparent rectangles"
  16. resize 590, 90
  17. move 300, 300
  18. show
  19. end
  20. def paintEvent event
  21. painter = Qt::Painter.new self
  22. drawRectangles painter
  23. painter.end
  24. end
  25. def drawRectangles painter
  26. painter.setPen Qt::NoPen
  27. for i in 1..10
  28. painter.setBrush Qt::Brush.new Qt::Color.new 0, 0, 255, i*25
  29. painter.drawRect 50*i, 20, 40, 40
  30. end
  31. end
  32. end
  33. app = Qt::Application.new ARGV
  34. QtApp.new
  35. app.exec

在示例中,我们将绘制十个具有不同透明度级别的矩形。

  1. painter.setPen Qt::NoPen

我们不用笔。

  1. for i in 1..10
  2. painter.setBrush Qt::Brush.new Qt::Color.new 0, 0, 255, i*25
  3. painter.drawRect 50*i, 20, 40, 40
  4. end

Color对象的最后一个参数是 alpha 透明度值。

用 Ruby Qt 绘图 - 图3

图:透明矩形

甜甜圈形状

在下面的示例中,我们通过旋转一堆椭圆来创建复杂的形状。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # This program draws a donut
  5. # shape
  6. #
  7. # author: jan bodnar
  8. # website: www.zetcode.com
  9. # last modified: June 2009
  10. require 'Qt'
  11. class QtApp < Qt::Widget
  12. def initialize
  13. super
  14. setWindowTitle "Donut"
  15. resize 350, 280
  16. move 300, 300
  17. show
  18. end
  19. def paintEvent event
  20. painter = Qt::Painter.new self
  21. drawDonut painter
  22. painter.end
  23. end
  24. def drawDonut painter
  25. painter.setRenderHint Qt::Painter::Antialiasing
  26. color = Qt::Color.new
  27. color.setNamedColor "#333333"
  28. pen = Qt::Pen.new color
  29. pen.setWidth 1
  30. painter.setPen pen
  31. w = width
  32. h = height
  33. painter.translate Qt::Point.new w/2, h/2
  34. 72.times do
  35. painter.drawEllipse -125, -40, 250, 80
  36. painter.rotate 5.0
  37. end
  38. end
  39. end
  40. app = Qt::Application.new ARGV
  41. QtApp.new
  42. app.exec

在此示例中,我们创建一个甜甜圈。 形状类似于曲奇,因此得名“甜甜圈”。

  1. color = Qt::Color.new
  2. color.setNamedColor "#333333"

我们可以使用十六进制表示法来创建颜色对象。

  1. w = width
  2. h = height

在这里,我们确定窗口的宽度和高度。

  1. painter.translate Qt::Point.new w/2, h/2

我们将坐标系移到窗口的中间。 这样,我们使绘图在数学上更容易。

  1. 72.times do
  2. painter.drawEllipse -125, -40, 250, 80
  3. painter.rotate 5.0
  4. end

我们绘制一个椭圆对象 72 次。 每次,我们将椭圆旋转 5 度。 这将创建我们的甜甜圈形状。

用 Ruby Qt 绘图 - 图4

图:多纳圈

绘制文字

在最后一个示例中,我们将在窗口上绘制文本。

  1. #!/usr/bin/ruby
  2. # ZetCode Ruby Qt tutorial
  3. #
  4. # This program draws text
  5. # on the window
  6. #
  7. # author: jan bodnar
  8. # website: www.zetcode.com
  9. # last modified: June 2009
  10. require 'Qt'
  11. class QtApp < Qt::Widget
  12. def initialize
  13. super
  14. setWindowTitle "Soulmate"
  15. resize 370, 240
  16. move 300, 300
  17. show
  18. end
  19. def paintEvent event
  20. painter = Qt::Painter.new self
  21. drawText painter
  22. painter.end
  23. end
  24. def drawText painter
  25. painter.setBrush Qt::Brush.new Qt::Color.new 25, 25, 25
  26. painter.setFont Qt::Font.new "Purisa", 10
  27. painter.drawText Qt::Point.new(20, 30),
  28. "Most relationships seem so transitory"
  29. painter.drawText Qt::Point.new(20, 60),
  30. "They're good but not the permanent one"
  31. painter.drawText Qt::Point.new(20, 120),
  32. "Who doesn't long for someone to hold"
  33. painter.drawText Qt::Point.new(20, 150),
  34. "Who knows how to love without being told"
  35. painter.drawText Qt::Point.new(20, 180),
  36. "Somebody tell me why I'm on my own"
  37. painter.drawText Qt::Point.new(20, 210),
  38. "If there's a soulmate for everyone"
  39. end
  40. end
  41. app = Qt::Application.new ARGV
  42. QtApp.new
  43. app.exec

我们在窗口上画一首歌歌词。

  1. painter.setFont Qt::Font.new "Purisa", 10

我们为文本设置了 Purisa 字体。

  1. painter.drawText Qt::Point.new(20, 30),
  2. "Most relationships seem so transitory"

drawText方法用于绘制文本。

用 Ruby Qt 绘图 - 图5

图:绘制文本

在 Ruby Qt 编程教程的这一部分中,我们做了一些绘图。