Archive:Development/Tutorials/Qt4 Ruby Tutorial/Chapter 10 (zh TW): Difference between revisions

From KDE TechBase
(Created page with '{{Template:I18n/Language Navigation Bar_(zh_TW)|Development/Tutorials/Qt4 Ruby Tutorial/Chapter 10}} {{TutorialBrowser_(zh_TW)| series=[[Development/Tutorials/Qt4_Ruby_Tutorial...')
 
 
(3 intermediate revisions by 2 users not shown)
Line 9: Line 9:
pre=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_09_(zh_TW)|教學 9 - With Cannon You Can]]|
pre=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_09_(zh_TW)|教學 9 - With Cannon You Can]]|


next=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_11|教學 11 - Giving It a Shot]]
next=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_11_(zh_TW)|教學 11 - Giving It a Shot]]
}}
}}
== Smooth as Silk ==
== Smooth as Silk ==
Line 19: Line 19:


===概覽===
===概覽===
In this example, we add a force control.
在這個範例中,我們增加了力量(force)控制。


===一行一行的瀏覽===
===一行一行的瀏覽===
'''[http://www.darshancomputing.com/qt4-qtruby-tutorial/tutorial/t10/cannon.rb cannon.rb]'''
'''[http://www.darshancomputing.com/qt4-qtruby-tutorial/tutorial/t10/cannon.rb cannon.rb]'''


The '''<tt>CannonField</tt>''' now has a force value in addition to the angle.
'''<tt>CannonField</tt>''' 現在除了角度外,又加入力量值。


<code ruby>
<syntaxhighlight lang="ruby">
signals 'angleChanged(int)', 'forceChanged(int)'
signals 'angleChanged(int)', 'forceChanged(int)'
slots 'setAngle(int)', 'setForce(int)'
slots 'setAngle(int)', 'setForce(int)'
</code>
</syntaxhighlight>


The interface to the force follows the same practice as for the angle.
力量的介面遵循和角度相同的寫法。


<code ruby>
<syntaxhighlight lang="ruby">
def initialize(parent = nil)
def initialize(parent = nil)
   super()
   super()
Line 43: Line 43:
   setAutoFillBackground(true)
   setAutoFillBackground(true)
end
end
</code>
</syntaxhighlight>


The force '''<tt>@currentForce</tt>''' is initialized to zero.
力量 '''<tt>@currentForce</tt>''' 初始化為零。


<code ruby>
<syntaxhighlight lang="ruby">
def setAngle(angle)
def setAngle(angle)
   if angle < 5
   if angle < 5
Line 63: Line 63:
   emit angleChanged(@currentAngle)
   emit angleChanged(@currentAngle)
end
end
</code>
</syntaxhighlight>


We have made a slight change in the '''<tt>setAngle()</tt>''' function. It repaints only the portion of the widget that contains the cannon.
我們在 '''<tt>setAngle()</tt>''' 函式作了一點輕微的改變。它只有重畫 widget 中包含加農砲的部分。


<code ruby>
<syntaxhighlight lang="ruby">
def setForce(force)
def setForce(force)
   if force < 0
   if force < 0
Line 79: Line 79:
   emit forceChanged(@currentForce)
   emit forceChanged(@currentForce)
end
end
</code>
</syntaxhighlight>


The implementation of '''<tt>setForce()</tt>''' is quite similar to that of '''<tt>setAngle()</tt>'''. The only difference is that because we don't show the force value, we don't need to repaint the widget.
'''<tt>setForce()</tt>''' 的實現相當類似 '''<tt>setAngle()</tt>'''。唯一的差別是,因為我們沒有顯示力量值,所以不需要重繪 widget。


<code ruby>
<syntaxhighlight lang="ruby">
def paintEvent(event)
def paintEvent(event)
   painter = Qt::Painter.new(self)
   painter = Qt::Painter.new(self)
Line 96: Line 96:
   painter.end()
   painter.end()
end
end
</code>
</syntaxhighlight>


We paint as in Chapter 9.
我們像第9章一樣繪製。


<code ruby>
<syntaxhighlight lang="ruby">
def cannonRect()
def cannonRect()
   result = Qt::Rect.new(0, 0, 50, 50)
   result = Qt::Rect.new(0, 0, 50, 50)
Line 106: Line 106:
   return result
   return result
end
end
</code>
</syntaxhighlight>


The '''<tt>cannonRect()</tt>''' function returns the rectangle enclosing the cannon in widget coordinates. First we create a rectangle with the size 50 x 50 and then move it so its bottom-left corner is equal to the widget's own bottom-left corner.
'''<tt>cannonRect()</tt>''' 函式返回 widget 坐標中封裝加農砲的矩形。首先,我們建立一個大小50×50的矩形。然後移動它,所以它的左下角等同於 widget 自己的左下角。


The [http://doc.qt.nokia.com/latest/qwidget.html#rect-prop Qt::Widget::rect()] function returns the widget's enclosing rectangle in the widget's own coordinates. The top-left corner of the rectangle is always (0, 0).
[http://doc.qt.nokia.com/latest/qwidget.html#rect-prop Qt::Widget::rect()] 函式返回在 widget 坐標中封裝 widget 自己矩形。矩形的左上角永遠是(0,0)。


'''[http://www.darshancomputing.com/qt4-qtruby-tutorial/tutorial/t10/t10.rb t10.rb]'''
'''[http://www.darshancomputing.com/qt4-qtruby-tutorial/tutorial/t10/t10.rb t10.rb]'''


The constructor is mostly the same, but some new bits have been added.
建構子大部分相同,但新增了一些東西。


<code ruby>
<syntaxhighlight lang="ruby">
force = LCDRange.new()
force = LCDRange.new()
force.setRange(10, 50)
force.setRange(10, 50)
</code>
</syntaxhighlight>


We add a second '''<tt>LCDRange</tt>''', which will be used to set the force.
我們加入第二個 '''<tt>LCDRange</tt>''',用來設定力量。


<code ruby>
<syntaxhighlight lang="ruby">
connect(force, SIGNAL('valueChanged(int)'),
connect(force, SIGNAL('valueChanged(int)'),
         cannonField, SLOT('setForce(int)'))
         cannonField, SLOT('setForce(int)'))
connect(cannonField, SIGNAL('forceChanged(int)'),
connect(cannonField, SIGNAL('forceChanged(int)'),
         force, SLOT('setValue(int)'))
         force, SLOT('setValue(int)'))
</code>
</syntaxhighlight>


We connect the '''<tt>force</tt>''' widget and the '''<tt>cannonField</tt>''' widget, just like we did for the '''<tt>angle</tt>''' widget.
我們連接 '''<tt>force</tt>''' widget '''<tt>cannonField</tt>''' widget,就像我們為 '''<tt>angle</tt>''' widget 所作的。


<code ruby>
<syntaxhighlight lang="ruby">
leftLayout = Qt::VBoxLayout.new()
leftLayout = Qt::VBoxLayout.new()
leftLayout.addWidget(angle)
leftLayout.addWidget(angle)
Line 142: Line 142:
gridLayout.addWidget(cannonField, 1, 1, 2, 1)
gridLayout.addWidget(cannonField, 1, 1, 2, 1)
gridLayout.setColumnStretch(1, 10)
gridLayout.setColumnStretch(1, 10)
</code>
</syntaxhighlight>


In Chapter 9, we put '''<tt>angle</tt>''' in the lower-left cell of the layout. Now we want to have two widgets in that cell, so we make a vertical box, put the vertical box in the grid cell, and put each of '''<tt>angle</tt>''' and '''<tt>range</tt>''' in the vertical box.
在第9章中,我們把 '''<tt>angle</tt>''' 放在佈局的左下格。現在,我們想有兩個 widget在該格中,所以我們做一個 vertical box,把 vertical box 放在網格中,並且把 '''<tt>angle</tt>''' '''<tt>range</tt>''' 放入 vertical box。


<code ruby>
<syntaxhighlight lang="ruby">
force.setValue(25)
force.setValue(25)
</code>
</syntaxhighlight>


We initialize the force value to 25.
我們初始化力量值為25。


===執行應用程式===
===執行應用程式===
We now have a force control.
我們現在有力量控制了。


===練習===
===練習===
Make the size of the cannon barrel be dependent on the force.
使砲管的大小依據力量的變化。


Put the cannon in the bottom-right corner.
把加農砲放在右下角。


Try adding a better keyboard interface. For example, make + and - increase and decrease the force and enter shoot. If you're bothered by the way the '''<tt>Left</tt>''' and '''<tt>Right</tt>''' keys work, change that too. [Hint: Reimplement [http://doc.qt.nokia.com/latest/qwidget.html#keyPressEvent Qt::Widget::keyPressEvent()].]
嘗試增加一個更好的鍵盤介面。例如,用+-來增加和減少力量,並用 enter 發射。如果你對'''<tt></tt>''''''<tt></tt>'''方向鍵的運作的方式感到困擾,也更改它吧。[提示:重新實作 [http://doc.qt.nokia.com/latest/qwidget.html#keyPressEvent Qt::Widget::keyPressEvent()]]


[[Category:Ruby]]
[[Category:Ruby]]

Latest revision as of 15:54, 23 June 2013

Template:I18n/Language Navigation Bar (zh TW)

Template:TutorialBrowser (zh TW)

Smooth as Silk

檔案:

概覽

在這個範例中,我們增加了力量(force)控制。

一行一行的瀏覽

cannon.rb

CannonField 現在除了角度外,又加入力量值。

signals 'angleChanged(int)', 'forceChanged(int)'
slots 'setAngle(int)', 'setForce(int)'

力量的介面遵循和角度相同的寫法。

def initialize(parent = nil)
  super()

  @currentAngle = 45
  @currentForce = 0

  setPalette(Qt::Palette.new(Qt::Color.new(250, 250, 200)))
  setAutoFillBackground(true)
end

力量 @currentForce 初始化為零。

def setAngle(angle)
  if angle < 5
    angle = 5
  elsif angle > 70
    angle = 70
  end

  if @currentAngle == angle
    return
  end

  @currentAngle = angle
  update(cannonRect())
  emit angleChanged(@currentAngle)
end

我們在 setAngle() 函式作了一點輕微的改變。它只有重畫 widget 中包含加農砲的部分。

def setForce(force)
  if force < 0
    force = 0
  end
  if @currentForce == force
    return
  end

  @currentForce = force
  emit forceChanged(@currentForce)
end

setForce() 的實現相當類似 setAngle()。唯一的差別是,因為我們沒有顯示力量值,所以不需要重繪 widget。

def paintEvent(event)
  painter = Qt::Painter.new(self)

  painter.setPen(Qt::NoPen)
  painter.setBrush(Qt::Brush.new(Qt::blue))

  painter.translate(0, height())
  painter.drawPie(Qt::Rect.new(-35, -35, 70, 70), 0, 90 * 16)
  painter.rotate(-@currentAngle)
  painter.drawRect(Qt::Rect.new(30, -5, 20, 10))
  painter.end()
end

我們像第9章一樣繪製。

def cannonRect()
  result = Qt::Rect.new(0, 0, 50, 50)
  result.moveBottomLeft(rect().bottomLeft())
  return result
end

cannonRect() 函式返回 widget 坐標中封裝加農砲的矩形。首先,我們建立一個大小50×50的矩形。然後移動它,所以它的左下角等同於 widget 自己的左下角。

Qt::Widget::rect() 函式返回在 widget 坐標中封裝 widget 自己矩形。矩形的左上角永遠是(0,0)。

t10.rb

建構子大部分相同,但新增了一些東西。

force = LCDRange.new()
force.setRange(10, 50)

我們加入第二個 LCDRange,用來設定力量。

connect(force, SIGNAL('valueChanged(int)'),
         cannonField, SLOT('setForce(int)'))
connect(cannonField, SIGNAL('forceChanged(int)'),
         force, SLOT('setValue(int)'))

我們連接 force widget 和 cannonField widget,就像我們為 angle widget 所作的。

leftLayout = Qt::VBoxLayout.new()
leftLayout.addWidget(angle)
leftLayout.addWidget(force)

gridLayout = Qt::GridLayout.new()
gridLayout.addWidget(quit, 0, 0)
gridLayout.addLayout(leftLayout, 1, 0)
gridLayout.addWidget(cannonField, 1, 1, 2, 1)
gridLayout.setColumnStretch(1, 10)

在第9章中,我們把 angle 放在佈局的左下格。現在,我們想有兩個 widget在該格中,所以我們做一個 vertical box,把 vertical box 放在網格中,並且把 anglerange 放入 vertical box。

force.setValue(25)

我們初始化力量值為25。

執行應用程式

我們現在有力量控制了。

練習

使砲管的大小依據力量的變化。

把加農砲放在右下角。

嘗試增加一個更好的鍵盤介面。例如,用+和-來增加和減少力量,並用 enter 發射。如果你對方向鍵的運作的方式感到困擾,也更改它吧。[提示:重新實作 Qt::Widget::keyPressEvent()。]