返回介绍

Custom widget in Qyoto

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

In this part of the Visual Basic Qyoto 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.

burning.vb

Imports Qyoto

NameSpace Burning

Public Class Burning 
  Inherits QWidget

  Const PANEL_HEIGHT As Integer = 30
  Const DISTANCE As Integer = 19
  Const LINE_WIDTH As Integer = 5
  Const DIVISIONS As Integer = 10
  
  Const FULL_CAPACITY As Double = 700.0
  Const MAX_CAPACITY As Double = 750.0
  
  Dim redColor As New QColor(255, 175, 175)
  Dim yellowColor As New QColor(255, 255, 184)

  Dim parent As QWidget 
  
  Dim num() As String = { _
    "75", "150", "225", "300", _
    "375", "450", "525", "600", _
    "675" _
  }
  
  Public Sub New(ByVal parent As QWidget) 
    Me.parent = parent
    MinimumHeight = PANEL_HEIGHT
  End Sub
  

  Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent) 

    Dim painter As New QPainter(Me)
    
    Me.DrawWidget(painter)
    painter.End()
    
  End Sub

  Private Sub DrawWidget(ByVal painter As QPainter) 
    
    Dim burn As CustomWidget.VBQApp = CType(parent, CustomWidget.VBQApp)

    Dim slid_width As Double = burn.GetCurrentWidth()
    Dim width As Double = Size.Width()
    Dim move As Double = width / DIVISIONS

    Dim till As Double = (width / MAX_CAPACITY) * slid_width
    Dim full As Double = (width / MAX_CAPACITY) * FULL_CAPACITY

    If slid_width > FULL_CAPACITY

      painter.SetPen(New QPen(New QBrush(yellowColor), 1))
      painter.SetBrush(New QBrush(yellowColor))
      painter.DrawRect(New QRectF(0, 0, full, PANEL_HEIGHT))
      painter.SetPen(New QPen(New QBrush(redColor), 1))
      painter.SetBrush(New QBrush(redColor))
      painter.DrawRect(New QRectF(full+1, 0, till-full, PANEL_HEIGHT))

    Else
    
      If (slid_width > 0) 
         painter.SetPen(New QPen(New QBrush(yellowColor), 1))
         painter.SetBrush(New QBrush(yellowColor))
         painter.DrawRect(New QRectF(0, 0, till, PANEL_HEIGHT))
      End If
      
    End If
    
    
    painter.SetPen(New QColor(90, 90, 90))
    painter.SetBrush(BrushStyle.NoBrush)
    painter.DrawRect(0, 0, Size.Width()-1, PANEL_HEIGHT-1)
    
    Dim newFont As QFont = painter.Font()
    newFont.SetPointSize(7)
    painter.SetFont(newFont)

    Dim metrics As New QFontMetrics(newFont)

    For i As Integer = 1 to num.Length
      painter.DrawLine(New QLineF(i*move, 1, i*move, LINE_WIDTH))

      Dim w As Integer = metrics.Width(num(i-1))

      painter.DrawText(New QPointF(i*move-w/2, DISTANCE), num(i-1))
    Next
    
  End Sub
  
End Class
  
End Namespace

In this file, we create the Burning widget.

Public Class Burning 
  Inherits QWidget

The custom widget is based on the QWidget widget.

Const PANEL_HEIGHT As Integer = 30
Const DISTANCE As Integer = 19
Const LINE_WIDTH As Integer = 5
Const DIVISIONS As Integer = 10

Const FULL_CAPACITY As Double = 700.0
Const MAX_CAPACITY As Double = 750.0

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 capacity of the media. After it is reached, overburning happens. This is visualized by a red color. The MAX_CAPACITY is the maximum capacity of a medium.

Dim num() As String = { _
  "75", "150", "225", "300", _
  "375", "450", "525", "600", _
  "675" _
}

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

Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent) 

  Dim painter As New QPainter(Me)
  
  Me.DrawWidget(painter)
  painter.End()
  
End Sub

The drawing of the custom widget is delegated to the DrawWidget() method.

Dim burn As CustomWidget.VBQApp = CType(parent, CustomWidget.VBQApp)

We retrieve the reference to the parent widget.

Dim slid_width As Double = burn.GetCurrentWidth()

We use it to get the currently selected slider value.

Dim width As Double = Size.Width()

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

Dim till As Double = (width / MAX_CAPACITY) * slid_width
Dim full As Double = (width / MAX_CAPACITY) * FULL_CAPACITY

We use the width 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(New QPen(New QBrush(redColor), 1))
painter.SetBrush(New QBrush(redColor))
painter.DrawRect(New QRectF(full+1, 0, till-full, PANEL_HEIGHT))

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

painter.DrawRect(0, 0, Size.Width()-1, PANEL_HEIGHT-1)

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

painter.DrawLine(New QLineF(i*move, 1, i*move, LINE_WIDTH))

Here we draw the small vertical lines.

Dim w As Integer = metrics.Width(num(i-1))

painter.DrawText(New QPointF(i*move-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.

main.vb

Imports Qyoto

' ZetCode Mono Visual Basic Qt tutorial
'
' In this program, we create
' a custom widget
'
' @author jan bodnar
' website zetcode.com
' last modified May 2009

NameSpace CustomWidget

Public Class VBQApp 
  Inherits QWidget

  Const MAX_CAPACITY As Integer = 750

  Dim slider As QSlider
  Dim widget As QWidget
  Dim cur_width As Integer

  Public Sub New()
    Me.SetWindowTitle("The Burning Widget")

    Me.InitUI()

    Me.Resize(370, 200)
    Me.Move(300, 300)
    Me.Show()
  End Sub

  Private Sub InitUI() 
     
     slider = New QSlider(Qt.Orientation.Horizontal , Me)
     slider.Maximum = MAX_CAPACITY
     slider.SetGeometry(50, 50, 130, 30)

     Connect(slider, SIGNAL("valueChanged(int)"), Me, _
        SLOT("ValueChanged(int)"))
     
     Dim vbox As New QVBoxLayout(Me)
     Dim hbox As New QHBoxLayout

     vbox.AddStretch(1)

     widget = New Burning.Burning(Me)
     hbox.AddWidget(widget, 0)

     vbox.AddLayout(hbox)

     SetLayout(vbox)
     
  End Sub

  <Q_SLOT()> _
  Public Sub ValueChanged(ByVal val As Integer) 
    cur_width = val
    widget.Repaint()
  End Sub
  

  Public Function GetCurrentWidth() As Integer
    Return cur_width
  End Function
  

  Public Shared Sub Main(ByVal args() As String)
    Dim qapp As New QApplication(args)
    Dim app As New VBQApp
    QApplication.Exec()
  End Sub

End Class

NameSpace CustomWidget

This is the main file. Here we create the slider widget and use our custom widget.

widget = New Burning.Burning(Me)
hbox.AddWidget(widget, 0)

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

<Q_SLOT()> _
Public Sub ValueChanged(ByVal val As Integer) 
  cur_width = val
  widget.Repaint()
End Sub

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

Public Function GetCurrentWidth() As Integer
  Return cur_width
End Function

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 Visual Basic Qyoto tutorial, we have demonstrated how to create a custom widget.

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

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

发布评论

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