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

From KDE TechBase
No edit summary
 
(5 intermediate revisions by 2 users not shown)
Line 9: Line 9:
pre=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_04_(zh_TW)|教學 4 - Let There Be Widget]]|
pre=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_04_(zh_TW)|教學 4 - Let There Be Widget]]|


next=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_06|教學 6 - Building Blocks Galore!]]
next=[[Development/Tutorials/Qt4_Ruby_Tutorial/Chapter_06_(zh_TW)|教學 6 - Building Blocks Galore!]]
}}
}}
== Building Blocks ==
== Building Blocks ==
Line 19: Line 19:
這個範例展示如何建立數個 widget,並且使用訊號和槽連接它們在一起。以及如何處理調整大小。
這個範例展示如何建立數個 widget,並且使用訊號和槽連接它們在一起。以及如何處理調整大小。


<code ruby>
<syntaxhighlight lang="ruby">
require 'Qt4'
require 'Qt4'


Line 51: Line 51:
widget.show()
widget.show()
app.exec()
app.exec()
</code>
</syntaxhighlight>


===一行一行的瀏覽===
===一行一行的瀏覽===
<code ruby>
<syntaxhighlight lang="ruby">
lcd = Qt::LCDNumber.new(2)
lcd = Qt::LCDNumber.new(2)
</code>
</syntaxhighlight>


'''<tt>lcd</tt>''' 是一個 [http://doc.qt.nokia.com/latest/qlcdnumber.html Qt::LCDNumber],以類似 LCD 方式顯示數字的 widget。此實例設定為顯示兩位數。
'''<tt>lcd</tt>''' 是一個 [http://doc.qt.nokia.com/latest/qlcdnumber.html Qt::LCDNumber],以類似 LCD 方式顯示數字的 widget。此實例設定為顯示兩位數。


<code ruby>
<syntaxhighlight lang="ruby">
slider = Qt::Slider.new(Qt::Horizontal)
slider = Qt::Slider.new(Qt::Horizontal)
slider.setRange(0, 99)
slider.setRange(0, 99)
slider.setValue(0)
slider.setValue(0)
</code>
</syntaxhighlight>


使用者可以使用[http://doc.qt.nokia.com/latest/qslider.html Qt::Slider] widget 在範圍內調整整數值。在這裡,我們建立水平的 [http://doc.qt.nokia.com/latest/qslider.html Qt::Slider],設定它的最小值為0、最大值為99,而初始值為0。
使用者可以使用[http://doc.qt.nokia.com/latest/qslider.html Qt::Slider] widget 在範圍內調整整數值。在這裡,我們建立水平的 [http://doc.qt.nokia.com/latest/qslider.html Qt::Slider],設定它的最小值為0、最大值為99,而初始值為0。


<code ruby>
<syntaxhighlight lang="ruby">
    connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)'))
connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)'))
</code>
</syntaxhighlight>


這裡我們使用[http://doc.qt.nokia.com/latest/signalsandslots.html 訊號和槽]機制連接 slider 的 [http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] 訊號到 LCD number 的 display() 槽。
這裡我們使用[http://doc.qt.nokia.com/latest/signalsandslots.html 訊號和槽]機制連接 slider 的 [http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] 訊號到 LCD number 的 display() 槽。
Line 76: Line 76:
每當 slider 的值變化時,它會藉由發出(emit)[http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] 訊號,傳送新的值。因為這個訊號連接到 LCD number 的 [http://doc.qt.nokia.com/latest/qlcdnumber.html#intValue-prop QLCDNumber::display()] 槽,當訊號傳送時,槽就會被呼叫。這兩個物件彼此都不知道對方。這就是組件程式設計(component programming)的要素。
每當 slider 的值變化時,它會藉由發出(emit)[http://doc.qt.nokia.com/latest/qabstractslider.html#valueChanged QAbstractSlider::valueChanged()] 訊號,傳送新的值。因為這個訊號連接到 LCD number 的 [http://doc.qt.nokia.com/latest/qlcdnumber.html#intValue-prop QLCDNumber::display()] 槽,當訊號傳送時,槽就會被呼叫。這兩個物件彼此都不知道對方。這就是組件程式設計(component programming)的要素。


<code ruby>
<syntaxhighlight lang="ruby">
layout = Qt::VBoxLayout.new()
layout = Qt::VBoxLayout.new()
layout.addWidget(quit)
layout.addWidget(quit)
Line 82: Line 82:
layout.addWidget(slider)
layout.addWidget(slider)
setLayout(layout)
setLayout(layout)
</code>
</syntaxhighlight>


'''<tt>MyWidget</tt>''' 現在使用 [http://doc.qt.nokia.com/latest/qvboxlayout.html Qt::VBoxLayout] 管理其子 widget 的幾何。For that reason, we don't need to specify the screen coordinates for each widget like we did in Chapter 4. In addition, using a layout ensures that the child widgets are resized when the window is resized. Then we add the '''<tt>quit</tt>''', '''<tt>lcd</tt>''', and '''<tt>slider</tt>''' widgets to the layout using [http://doc.qt.nokia.com/latest/qboxlayout.html#addWidget Qt::BoxLayout::addWidget()].
'''<tt>MyWidget</tt>''' 現在使用 [http://doc.qt.nokia.com/latest/qvboxlayout.html Qt::VBoxLayout] 管理其子 widget 的幾何形狀。因為這個原因,我們不需要像第4章那樣為每個widget 指定螢幕坐標。此外,使用佈局(layout)確保當視窗大小改變時,其子 widget 會調整大小。然後我們使用 [http://doc.qt.nokia.com/latest/qboxlayout.html#addWidget Qt::BoxLayout::addWidget()] 加入'''<tt>quit</tt>''''''<tt>lcd</tt>''',和 '''<tt>slider</tt>''' widget 到佈局中。


The [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] function installs the layout on '''<tt>MyWidget</tt>'''. This makes the layout a child widget of '''<tt>MyWidget</tt>''' so we don't have to worry about deleting it; it will be deleted together with MyWidget. Also, the call to [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] automatically reparents the widgets in the layout so that they are children of '''<tt>MyWidget</tt>'''. Because of this, we didn't need to specify '''<tt>self</tt>''' as the parent for the '''<tt>quit</tt>''', '''<tt>lcd</tt>''', and '''<tt>slider</tt>''' widgets.
[http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] 函式將這個佈局安裝在 '''<tt>MyWidget</tt>''' 中。這使得佈局成為 '''<tt>MyWidget</tt>''' 的子 widget,所以不用擔心刪除它的問題,它會與 '''<tt>MyWidget</tt>''' 一起被刪除。此外,呼叫 [http://doc.qt.nokia.com/latest/qwidget.html#setLayout Qt::Widget::setLayout()] 會自動重新設定佈局中 widget 的父 widget,使他們成為 '''<tt>MyWidget</tt>''' 的子  widget。正因如此,我們不需要指定 '''<tt>self</tt>''' '''<tt>quit</tt>''''''<tt>lcd</tt>''',和 '''<tt>slider</tt>''' widget 的父 widget。


In Qt, widgets are either children of other widgets (e.g. '''<tt>self</tt>'''), or they have no parent. A widget can be ''added'' to a layout, in which case the layout becomes responsible for managing the geometry of that widget, but the layout can never act as a parent itself. Indeed, [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget]'s constructor takes a [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget] pointer for the parent, and [http://doc.qt.nokia.com/latest/qlayout.html Qt::Layout] doesn't inherit from [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget].
Qt 中,widget 可以是其他 widget(如 '''<tt>self</tt>''')的子 widget,或者他們沒有父 widget。widget 可以被''加入''到一個佈局,在這種情況下,佈局負責管理 widget 的幾何形狀,但佈局本身不能作為父 widget。事實上,[http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget] 的建構子使用一個 [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget] 指標指向父 widget,而且 [http://doc.qt.nokia.com/latest/qlayout.html Qt::Layout] 沒有繼承自 [http://doc.qt.nokia.com/latest/qwidget.html Qt::Widget]


===執行應用程式===
===執行應用程式===
The LCD number reflects everything you do to the slider, and the widget handles resizing well. Notice that the LCD number widget changes in size when the window is resized (because it can), but the others stay about the same (because otherwise they would look strange).
LCD number 反映了你對 slider 做的一切,而且這個 widget 也成功處理大小變動。請注意,當視窗大小調整時,LCD number widget 大小也會變動(因為它可以),但其他保持不變(否則他們看起來會很奇怪)。


===練習===
===練習===
Try changing the LCD number to add more digits or to change mode ([http://doc.qt.nokia.com/latest/qlcdnumber.html#mode-prop Qt::LCDNumber::setMode()]). You can even add four push buttons to set the number base.
嘗試修改 LCD number ,增加更多位數或更改模式([http://doc.qt.nokia.com/latest/qlcdnumber.html#mode-prop Qt::LCDNumber::setMode()])。您甚至可以增加四個按鈕來設定基數(number base)。
 
您還可以更改 slider 的範圍。


You can also change the slider's range.
也許使用 [http://doc.qt.nokia.com/latest/qspinbox.html Qt::SpinBox] 比 slider 更好?


Perhaps it would have been better to use [http://doc.qt.nokia.com/latest/qspinbox.html Qt::SpinBox] than a slider?
嘗試當 LCD number 溢出(overflow)時,使應用程式退出。


Try to make the application quit when the LCD number overflows.
[[Category:Ruby]]

Latest revision as of 15:39, 23 June 2013

Template:I18n/Language Navigation Bar (zh TW)

Template:TutorialBrowser (zh TW)

Building Blocks

檔案:

概覽

這個範例展示如何建立數個 widget,並且使用訊號和槽連接它們在一起。以及如何處理調整大小。

require 'Qt4'

class MyWidget < Qt::Widget
  def initialize()
    super()
    quit = Qt::PushButton.new('Quit')
    quit.setFont(Qt::Font.new('Times', 18, Qt::Font::Bold))
    
    lcd = Qt::LCDNumber.new(2)

    slider = Qt::Slider.new(Qt::Horizontal)
    slider.setRange(0, 99)
    slider.setValue(0)

    connect(quit, SIGNAL('clicked()'), $qApp, SLOT('quit()'))
    connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)'))

    layout = Qt::VBoxLayout.new()
    layout.addWidget(quit)
    layout.addWidget(lcd)
    layout.addWidget(slider)
    setLayout(layout)
  end
end

app = Qt::Application.new(ARGV)

widget = MyWidget.new()

widget.show()
app.exec()

一行一行的瀏覽

lcd = Qt::LCDNumber.new(2)

lcd 是一個 Qt::LCDNumber,以類似 LCD 方式顯示數字的 widget。此實例設定為顯示兩位數。

slider = Qt::Slider.new(Qt::Horizontal)
slider.setRange(0, 99)
slider.setValue(0)

使用者可以使用Qt::Slider widget 在範圍內調整整數值。在這裡,我們建立水平的 Qt::Slider,設定它的最小值為0、最大值為99,而初始值為0。

connect(slider, SIGNAL('valueChanged(int)'), lcd, SLOT('display(int)'))

這裡我們使用訊號和槽機制連接 slider 的 QAbstractSlider::valueChanged() 訊號到 LCD number 的 display() 槽。

每當 slider 的值變化時,它會藉由發出(emit)QAbstractSlider::valueChanged() 訊號,傳送新的值。因為這個訊號連接到 LCD number 的 QLCDNumber::display() 槽,當訊號傳送時,槽就會被呼叫。這兩個物件彼此都不知道對方。這就是組件程式設計(component programming)的要素。

layout = Qt::VBoxLayout.new()
layout.addWidget(quit)
layout.addWidget(lcd)
layout.addWidget(slider)
setLayout(layout)

MyWidget 現在使用 Qt::VBoxLayout 管理其子 widget 的幾何形狀。因為這個原因,我們不需要像第4章那樣為每個widget 指定螢幕坐標。此外,使用佈局(layout)確保當視窗大小改變時,其子 widget 會調整大小。然後我們使用 Qt::BoxLayout::addWidget() 加入quitlcd,和 slider widget 到佈局中。

Qt::Widget::setLayout() 函式將這個佈局安裝在 MyWidget 中。這使得佈局成為 MyWidget 的子 widget,所以不用擔心刪除它的問題,它會與 MyWidget 一起被刪除。此外,呼叫 Qt::Widget::setLayout() 會自動重新設定佈局中 widget 的父 widget,使他們成為 MyWidget 的子 widget。正因如此,我們不需要指定 selfquitlcd,和 slider widget 的父 widget。

在 Qt 中,widget 可以是其他 widget(如 self)的子 widget,或者他們沒有父 widget。widget 可以被加入到一個佈局,在這種情況下,佈局負責管理 widget 的幾何形狀,但佈局本身不能作為父 widget。事實上,Qt::Widget 的建構子使用一個 Qt::Widget 指標指向父 widget,而且 Qt::Layout 沒有繼承自 Qt::Widget

執行應用程式

LCD number 反映了你對 slider 做的一切,而且這個 widget 也成功處理大小變動。請注意,當視窗大小調整時,LCD number widget 大小也會變動(因為它可以),但其他保持不變(否則他們看起來會很奇怪)。

練習

嘗試修改 LCD number ,增加更多位數或更改模式(Qt::LCDNumber::setMode())。您甚至可以增加四個按鈕來設定基數(number base)。

您還可以更改 slider 的範圍。

也許使用 Qt::SpinBox 比 slider 更好?

嘗試當 LCD number 溢出(overflow)時,使應用程式退出。