2008年7月9日 星期三

QT-chap 7

從這一個章節開始程式碼就要寫在多個檔案中
然後檔案要如何分類在不同的資料夾,這是一個很重要的課題
當系統越來越大時,這個時候程式碼檔案要是分類的好
之後,別人要修改資料,就比較容易看懂這系統的架構是如何


#ifndef LCDRANGE_H
#define LCDRANGE_H
...
#endif

所有的預處理器指引指令以#開始
兩個大的預處理器分別為
#include:在目前檔案中插入另一個檔案
#define:讓編譯器可以定義可以在程式碼中使用的常數值
為了避免出現一個head file被包含不止一次的情況。
如果你沒有使用過它,這是開發中的一個很好的習慣。
#include把這個頭文件的全部都包含進去。
#ifndef#endif是相對應的
中間包的程式碼就是此head file的主要內容


class QSlider;

我們不需要在宣告此類別時使用到QSlider
只有在實作此類別時才會使用到
因此我們在此head file中先使用forward declaration
並罝在實作此類別的程式碼中(.cpp檔案)再include此qslider.h檔案
原文哩:
Because we don't need QSlider in the interface of the class,
only in the implementation,
we use a forward declaration of the class in the header file and include the header file for QSlider in the .cpp file.
透過這一個小技巧,可以讓編譯的速度變的更快一點
This makes the compilation of big projects much faster, because when a header file has changed, fewer files need to be recompiled. It can often speed up big compilations by a factor of two or more.


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

當要定義signal與slot時,必需要在類別前使用Q_OBJECT
必需要注意的是Q_OBJECT只能放在header file中,而不能放在.cpp file中


  int value() const;
public slots:
  void setValue( int );

signals:
  void valueChanged( int );

這裡宣告三個函數,其中setValue(int)為slots、valueChanged(int)則是signals
而通常我們宣告是宣告public slots、(private) signals


int value() const;

這裡要先說明const的特性

const int function(...) const

前面的const是表示此function return const int
那後面的const則是宣告此 method 不會動到object 裡面的資料
因此我們設定的這一個函數value就不可以動到物件的內容

這裡有一個對const解示不錯的說法
由右往左、用英文讀是最明確的了.
int 就是 int
int * 就是 pointer to int, 指向 int 的 pointer
int * const 就是 const pointer to int, 固定指標,指向 int
const int * 就是 pointer to const int, 指向 const int 的指標
const int * const 就是 const pointer to const int, 也就是固定的指標,指向一個 const int.
原文出處
一個類別只能發射它自己定義的或者繼承來的信號


在lcdrange.cpp檔案中

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

第一個之前就說過了
那第二個函數就是省略掉this,這一個參數

讓我們來看看當用戶操作這個slider的時候都發生了些什麼。
slider看到自己的值發生了改變,並發射了valueChanged()信號。
這個信號被連接到QLCDNumber的display()槽和LCDRange的valueChanged()信號。
是的,這是正確的。信號可以被連接到其它的信號。
當第一個信號被發射時,第二個信號也被發射。
所以,當這個信號被發射的時候,
LCDRange發射它自己的valueChanged()信號。
另外,QLCDNumber::display()被調用並顯示新的數字。

注意你並沒有保證執行的任何順序——
LCDRange::valueChanged()也許在QLCDNumber::display()之前或者之後發射,這是完全任意的。
這就是一個signal同時觸發兩個slot

參考資料:第七章

沒有留言: