ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 用 Ruby Qt 绘图 > 原文: [http://zetcode.com/gui/rubyqt/painting/](http://zetcode.com/gui/rubyqt/painting/) 在 Ruby Qt 编程教程的这一部分中,我们将进行绘图。 我们什么时候需要油漆? 在某些情况下,当我们需要从头开始创建小部件时。 在这种情况下,我们需要绘图。 或者我们想创建图表,特殊装饰,效果或小部件增强。 当我们在 Qt 库中进行绘图时,`Painter`类将发挥作用。 绘图事件通过`paintEvent`方法接收。 若要进行自定义绘图,我们必须重新实现此方法。 ## 图案 在 Qt 中,我们可以使用各种图案来填充形状的内部。 ```rb #!/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 ``` 在代码示例中,我们将绘制九个矩形,并用不同的画笔图案填充它们。 ```rb def paintEvent event painter = Qt::Painter.new self drawPatterns painter painter.end end ``` 当需要重绘窗口区域时,将调用`paintEvent`方法。 当我们调整窗口大小,最大化或最小化窗口时,就会发生这种情况。在此方法中,我们创建了`Painter`对象。 该对象用于在 Qt 中进行所有绘制。 绘图本身被委托给`drawPatterns`方法。 ```rb painter.setPen Qt::NoPen ``` 笔对象用于绘制形状的轮廓。 在我们的示例中,我们将不使用笔。 ```rb painter.setBrush Qt::HorPattern ``` 我们将水平图案设置为画笔。 ```rb painter.drawRect 10, 15, 90, 60 ``` 我们用当前的笔和画笔绘制一个矩形。 该方法的前两个参数是 x,y 坐标。 最后两个参数是矩形的宽度和高度。 ```rb painter.end ``` `end`方法完成绘制。 释放绘图时使用的所有资源。 ![Patterns](https://img.kancloud.cn/9a/a0/9aa03f30abece400abcdc7bede5e85f2_356x305.jpg) 图:图案 ## 形状 Qt 绘图 API 可以绘制各种形状。 以下编程代码示例将显示其中的一些。 ```rb #!/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 ``` 在此代码示例中,我们在窗口上绘制了九种不同的形状。 复杂路径,饼图,和弦,圆角矩形,多边形,矩形,基于字符的形状,圆形和椭圆形。 ```rb painter.setRenderHint Qt::Painter::Antialiasing ``` 我们在示例中使用抗锯齿。 抗锯齿形状看起来更好,但是绘制它们需要更多时间。 ```rb painter.setPen Qt::Color.new 150, 150, 150 painter.setBrush Qt::Brush.new Qt::Color.new 150, 150, 150 ``` 我们使用深灰色的笔和画笔绘制形状。 ```rb 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`类为绘图操作提供了一个容器。 画家路径是由许多图形构造块(例如矩形,椭圆形,直线和曲线)组成的对象。 ```rb 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 ``` 这三条线绘制了一个饼图,一个和弦和一个圆角矩形。 ```rb 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 ``` 我们使用五个点的数组来创建多边形。 ```rb baseline = Qt::PointF.new 20, 250 font = Qt::Font.new "Georgia", 55 path2 = Qt::PainterPath.new path2.addText baseline, font, "Q" painter.drawPath path2 ``` 这些线创建基于字符的形状。 ```rb painter.drawEllipse 140, 200, 60, 60 painter.drawEllipse 240, 200, 90, 60 ``` 这两条线分别创建一个圆和一个椭圆。 ![Shapes](https://img.kancloud.cn/47/8e/478eee4c52e3235b6b017ebb5a02264b_356x305.jpg) 图:形状 ## 透明矩形 透明度是能够透视材料的质量。 了解透明度的最简单方法是想象一块玻璃或水。 从技术上讲,光线可以穿过玻璃,这样我们就可以看到玻璃后面的物体。 在计算机图形学中,我们可以使用 alpha 合成实现透明效果。 Alpha 合成是将图像与背景组合以创建部分透明外观的过程。 合成过程使用 Alpha 通道。 (wikipedia.org,answers.com) ```rb #!/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 ``` 在示例中,我们将绘制十个具有不同透明度级别的矩形。 ```rb painter.setPen Qt::NoPen ``` 我们不用笔。 ```rb 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 透明度值。 ![Transparent rectangles](https://img.kancloud.cn/06/28/062818c5414b78ef1b9b1b6cda348f85_596x115.jpg) 图:透明矩形 ## 甜甜圈形状 在下面的示例中,我们通过旋转一堆椭圆来创建复杂的形状。 ```rb #!/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 ``` 在此示例中,我们创建一个甜甜圈。 形状类似于曲奇,因此得名“甜甜圈”。 ```rb color = Qt::Color.new color.setNamedColor "#333333" ``` 我们可以使用十六进制表示法来创建颜色对象。 ```rb w = width h = height ``` 在这里,我们确定窗口的宽度和高度。 ```rb painter.translate Qt::Point.new w/2, h/2 ``` 我们将坐标系移到窗口的中间。 这样,我们使绘图在数学上更容易。 ```rb 72.times do painter.drawEllipse -125, -40, 250, 80 painter.rotate 5.0 end ``` 我们绘制一个椭圆对象 72 次。 每次,我们将椭圆旋转 5 度。 这将创建我们的甜甜圈形状。 ![Donut](https://img.kancloud.cn/42/4e/424e9b56c7a6cc6373c5f03e71b8aa83_356x305.jpg) 图:多纳圈 ## 绘制文字 在最后一个示例中,我们将在窗口上绘制文本。 ```rb #!/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 ``` 我们在窗口上画一首歌歌词。 ```rb painter.setFont Qt::Font.new "Purisa", 10 ``` 我们为文本设置了 Purisa 字体。 ```rb painter.drawText Qt::Point.new(20, 30), "Most relationships seem so transitory" ``` `drawText`方法用于绘制文本。 ![Drawing text](https://img.kancloud.cn/31/42/314270fefc07a0f0ae5b5ab148fd5a47_376x265.jpg) 图:绘制文本 在 Ruby Qt 编程教程的这一部分中,我们做了一些绘图。