Archive:Development/Tutorials/Qt4 Ruby Tutorial/Chapter 10 (zh TW): Difference between revisions
No edit summary |
Neverendingo (talk | contribs) m (Text replace - "<code ruby>" to "<syntaxhighlight lang="ruby">") |
||
Line 26: | Line 26: | ||
'''<tt>CannonField</tt>''' 現在除了角度外,又加入力量值。 | '''<tt>CannonField</tt>''' 現在除了角度外,又加入力量值。 | ||
< | <syntaxhighlight lang="ruby"> | ||
signals 'angleChanged(int)', 'forceChanged(int)' | signals 'angleChanged(int)', 'forceChanged(int)' | ||
slots 'setAngle(int)', 'setForce(int)' | slots 'setAngle(int)', 'setForce(int)' | ||
Line 33: | Line 33: | ||
力量的介面遵循和角度相同的寫法。 | 力量的介面遵循和角度相同的寫法。 | ||
< | <syntaxhighlight lang="ruby"> | ||
def initialize(parent = nil) | def initialize(parent = nil) | ||
super() | super() | ||
Line 47: | Line 47: | ||
力量 '''<tt>@currentForce</tt>''' 初始化為零。 | 力量 '''<tt>@currentForce</tt>''' 初始化為零。 | ||
< | <syntaxhighlight lang="ruby"> | ||
def setAngle(angle) | def setAngle(angle) | ||
if angle < 5 | if angle < 5 | ||
Line 67: | Line 67: | ||
我們在 '''<tt>setAngle()</tt>''' 函式作了一點輕微的改變。它只有重畫 widget 中包含加農砲的部分。 | 我們在 '''<tt>setAngle()</tt>''' 函式作了一點輕微的改變。它只有重畫 widget 中包含加農砲的部分。 | ||
< | <syntaxhighlight lang="ruby"> | ||
def setForce(force) | def setForce(force) | ||
if force < 0 | if force < 0 | ||
Line 83: | Line 83: | ||
'''<tt>setForce()</tt>''' 的實現相當類似 '''<tt>setAngle()</tt>'''。唯一的差別是,因為我們沒有顯示力量值,所以不需要重繪 widget。 | '''<tt>setForce()</tt>''' 的實現相當類似 '''<tt>setAngle()</tt>'''。唯一的差別是,因為我們沒有顯示力量值,所以不需要重繪 widget。 | ||
< | <syntaxhighlight lang="ruby"> | ||
def paintEvent(event) | def paintEvent(event) | ||
painter = Qt::Painter.new(self) | painter = Qt::Painter.new(self) | ||
Line 100: | Line 100: | ||
我們像第9章一樣繪製。 | 我們像第9章一樣繪製。 | ||
< | <syntaxhighlight lang="ruby"> | ||
def cannonRect() | def cannonRect() | ||
result = Qt::Rect.new(0, 0, 50, 50) | result = Qt::Rect.new(0, 0, 50, 50) | ||
Line 116: | Line 116: | ||
建構子大部分相同,但新增了一些東西。 | 建構子大部分相同,但新增了一些東西。 | ||
< | <syntaxhighlight lang="ruby"> | ||
force = LCDRange.new() | force = LCDRange.new() | ||
force.setRange(10, 50) | force.setRange(10, 50) | ||
Line 123: | Line 123: | ||
我們加入第二個 '''<tt>LCDRange</tt>''',用來設定力量。 | 我們加入第二個 '''<tt>LCDRange</tt>''',用來設定力量。 | ||
< | <syntaxhighlight lang="ruby"> | ||
connect(force, SIGNAL('valueChanged(int)'), | connect(force, SIGNAL('valueChanged(int)'), | ||
cannonField, SLOT('setForce(int)')) | cannonField, SLOT('setForce(int)')) | ||
Line 132: | Line 132: | ||
我們連接 '''<tt>force</tt>''' widget 和 '''<tt>cannonField</tt>''' widget,就像我們為 '''<tt>angle</tt>''' widget 所作的。 | 我們連接 '''<tt>force</tt>''' widget 和 '''<tt>cannonField</tt>''' widget,就像我們為 '''<tt>angle</tt>''' widget 所作的。 | ||
< | <syntaxhighlight lang="ruby"> | ||
leftLayout = Qt::VBoxLayout.new() | leftLayout = Qt::VBoxLayout.new() | ||
leftLayout.addWidget(angle) | leftLayout.addWidget(angle) | ||
Line 146: | Line 146: | ||
在第9章中,我們把 '''<tt>angle</tt>''' 放在佈局的左下格。現在,我們想有兩個 widget在該格中,所以我們做一個 vertical box,把 vertical box 放在網格中,並且把 '''<tt>angle</tt>''' 和 '''<tt>range</tt>''' 放入 vertical box。 | 在第9章中,我們把 '''<tt>angle</tt>''' 放在佈局的左下格。現在,我們想有兩個 widget在該格中,所以我們做一個 vertical box,把 vertical box 放在網格中,並且把 '''<tt>angle</tt>''' 和 '''<tt>range</tt>''' 放入 vertical box。 | ||
< | <syntaxhighlight lang="ruby"> | ||
force.setValue(25) | force.setValue(25) | ||
</code> | </code> |
Revision as of 20:43, 29 June 2011
Template:I18n/Language Navigation Bar (zh TW)
Template:TutorialBrowser (zh TW)
Smooth as Silk
檔案:
概覽
在這個範例中,我們增加了力量(force)控制。
一行一行的瀏覽
CannonField 現在除了角度外,又加入力量值。
<syntaxhighlight lang="ruby"> signals 'angleChanged(int)', 'forceChanged(int)' slots 'setAngle(int)', 'setForce(int)'
力量的介面遵循和角度相同的寫法。
<syntaxhighlight lang="ruby"> def initialize(parent = nil)
super()
@currentAngle = 45 @currentForce = 0
setPalette(Qt::Palette.new(Qt::Color.new(250, 250, 200))) setAutoFillBackground(true)
end
力量 @currentForce 初始化為零。
<syntaxhighlight lang="ruby"> 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 中包含加農砲的部分。
<syntaxhighlight lang="ruby"> def setForce(force)
if force < 0 force = 0 end if @currentForce == force return end
@currentForce = force emit forceChanged(@currentForce)
end
setForce() 的實現相當類似 setAngle()。唯一的差別是,因為我們沒有顯示力量值,所以不需要重繪 widget。
<syntaxhighlight lang="ruby"> 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章一樣繪製。
<syntaxhighlight lang="ruby"> 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)。
建構子大部分相同,但新增了一些東西。
<syntaxhighlight lang="ruby"> force = LCDRange.new() force.setRange(10, 50)
我們加入第二個 LCDRange,用來設定力量。
<syntaxhighlight lang="ruby"> connect(force, SIGNAL('valueChanged(int)'),
cannonField, SLOT('setForce(int)'))
connect(cannonField, SIGNAL('forceChanged(int)'),
force, SLOT('setValue(int)'))
我們連接 force widget 和 cannonField widget,就像我們為 angle widget 所作的。
<syntaxhighlight lang="ruby"> 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 放在網格中,並且把 angle 和 range 放入 vertical box。
<syntaxhighlight lang="ruby"> force.setValue(25)
我們初始化力量值為25。
執行應用程式
我們現在有力量控制了。
練習
使砲管的大小依據力量的變化。
把加農砲放在右下角。
嘗試增加一個更好的鍵盤介面。例如,用+和-來增加和減少力量,並用 enter 發射。如果你對左和右方向鍵的運作的方式感到困擾,也更改它吧。[提示:重新實作 Qt::Widget::keyPressEvent()。]