2008年7月9日 星期三

QT-chap 5

這一個範例是在介紹如何透過connect把幾個物件的signal與slot連接起來
之前是有介紹過如何使用connect
但是與這次不同的是
這一次多了參數的傳送
之前是當使用者按button之後,應用程式就離開
而這次則是調slider時,把數值傳送到lcd上顯示


class MyWidget : public QVBox
{
  public:
    MyWidget( QWidget *parent=0, const char *name=0 );
};

這次我們自定的Widget是由QVBox繼承過來的
QVBox會自動把我們加入的元件排列


MyWidget::MyWidget( QWidget *parent, const char *name ) : QVBox( parent, name )

剛剛是宣告建構子(constructor),現在是準備要定義實作的內容


QLCDNumber *lcd = new QLCDNumber( 2, this, "lcd" );

建立一個新的lcd物件,數字位數為2位,父視窗為this,此物件名稱為"lcd"


QSlider * slider = new QSlider( Horizontal, this, "slider" );
slider->setRange( 0, 99 );
slider->setValue( 0 );

建立一個slider物件,其父視窗也是this,並且設定範圍與初始值


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

這一章的重點就在這裡了
這裡原本我有一個問題
valueChanged的輸入參數是int且回傳型態是void
那它是在哪裡把要顯示的參數傳送給lcd的display函數呢?
結果仔細看完valueChanged的解說:
This signal is emitted when the slider value is changed, with the new slider value as an argument
才知道當它是signal時,會把新的slider值傳送出去
且在Qt signal&slot

另外還有一些重點
1. 有提到signal-slot之間的連接(或signal-signal)必須使用相同的參數型態以及相同的參數順序
2. 在Qt中,所有的類別若有signals或slots,則一定要載宣告最上方提及Q_OBJECT
3. signals和slots機制是type-safe:signal和其接受的slot必須要相符合,而compiler可以自動偵測type是否符合。
4. signals和slots機制是loosely coupled:發送signal的類別不需要知道哪一個slot會接受所發送的 signal。此機制會確保當你在"連接"(connect)了一個signal和slot後,slot會接受signal的參數並且正確執行。 signal和slot可接受任何數量、任何型態的參數,因此是完全的type-safe。
5. 所有的類別都是繼承至QObject或是其子類別,且可同時擁有signal和slot,因此,所有的訊息傳送與接收,都是物件;物件不必知道是誰接收了它發送的signal,這就達成了物件導向中的資訊封裝(information encapsulation),並確保物件可做為軟體元件(software component)。

在homework的部分新增了四個按紐來改變數字模式,分別改成16進位、10進位、8進位、2進位
因為,需要增加四個額外的按紐,當clicked時,要分別觸發四個改變LCDNumber的進位模式。
所以,需要新增四個slots
這裡要注意的是:
1. 當宣告slots function或signals function時,必需要在前頭加Q_OBJECT
2. Q_OBJECT必需宣告在header檔中,不能同時宣告在cpp檔中,會出現錯誤
3. 另外,需要使用到qApp時,必而包含qapplication.h
4. 當溢位時,可以使用LCDNumber的signals function:overflow()

沒有留言: