返回介绍

Custom widget in Ruby Qt

发布于 2025-02-22 22:19:47 字数 6749 浏览 0 评论 0 收藏 0

In this part of the Ruby Qt programming tutorial, we will create a custom widget.

Toolkits usually provide only the most common widgets like buttons, text widgets, sliders etc. No toolkit can provide all possible widgets. Programmers must create such widgets by themselves. They do it by using the drawing tools provided by the toolkit. There are two possibilities. A programmer can modify or enhance an existing widget. Or he can create a custom widget from scratch.

The Burning widget

In the next example, we will create a custom burning widget. This widget can be seen in applications like Nero or K3B. The widget will be created from scratch.

#!/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

In this file, we create the Burning widget.

class Burning < Qt::Widget 

The custom widget is based on the Widget widget.

PANEL_HEIGHT = 30
DISTANCE = 19
LINE_WIDTH = 5
DIVISIONS = 10
FULL_CAPACITY = 700
MAX_CAPACITY = 750

These are important constants. The PANEL_HEIGHT defines the height for the custom widget. The DISTANCE is the distance of the numbers on the scale from the top of their parent border. The LINE_WIDTH is the vertical line width. The DIVISIONS is the number of parts of the scale. The FULL_CAPACITY is the maximum capacity of the media. After it is reached, overburning happens. This is visualised by a red colour. The MAX_CAPACITY is the maximum capacity of a medium.

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

We use these numbers to build the scale of the Burning widget.

def paintEvent event

  painter = Qt::Painter.new self

  drawWidget painter
  painter.end
end

The drawing of the custom widget is delegated to the drawWidget method.

slid_width = @parent.getCurrentWidth

We use it to get the currently selected slider value.

w = width.to_f

We get the width of the widget. The width of the custom widget is dynamic. It can be resized by a user.

till = ((w / MAX_CAPACITY) * slid_width).to_f
full = ((w / MAX_CAPACITY) * FULL_CAPACITY).to_f

We use the w variable to do the transformations. Between the values of the scale and the custom widget's measures. Note that we use floating point values. We get greater precision in drawing.

painter.setPen @redColor
painter.setBrush Qt::Brush.new @redColor
painter.drawRect Qt::RectF.new full+1, 0, till-full, PANEL_HEIGHT

These three lines draw the red rectangle, indicating the overburning.

painter.drawRect 0, 0, w-1, PANEL_HEIGHT-1

This is the perimeter of the widget, the outside rectangle.

painter.drawLine Qt::LineF.new i*step, 1, i*step, LINE_WIDTH

Here we draw the small vertical lines.

w = metrics.width @num[i-1]
painter.drawText(Qt::PointF.new(i*step-w/2, DISTANCE), @num[i-1])

Here we draw the numbers of the scale. To precisely position the numbers, we must get the width of the string.

@widget = Burning.new self
hbox.addWidget @widget, 0

We create the instance of the Burning widget and add it to the horizontal box.

def onChanged val
  @cur_width = val
  @widget.repaint
end

When the value of the slider changes, we store it inside the @cur_width variable and repaint the custom widget.

def getCurrentWidth
return @cur_width
end

This method is called by the custom widget to get the actual slider value.

The Burning widget
Figure: The Burning widget

In this part of the Ruby Qt tutorial, we have demonstrated how to create a custom widget.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文