Qt入門(18)——使用訊號和槽連線控制元件
下面顯示瞭如何使用訊號和槽來建立自定義視窗部件,和如何使用更加複雜的方式把它們連線起來。
首先,原始檔被我們分成幾部分並放在放在t7目錄下。
t7/lcdrange.h包含LCDRange類定義。
t7/lcdrange.cpp包含LCDRange類實現。
t7/main.cpp包含MyWidget和main。
t7/lcdrange.h這個檔案主要利用了前面博文的main.cpp,在這裡只是說明一下改變了哪些。
#ifndef LCDRANGE_H
#define LCDRANGE_H
這裡是一個經典的C語句,為了避免出現一個標頭檔案被包含不止一次的情況。如果你沒有使用過它,這是開發中的一個很好的習慣。#ifndef需要把這個標頭檔案的全部都包含進去。
#include <qvbox.h>
qvbox.h被包含了。LCDRange繼承了QVBox,所以父類的標頭檔案必須被包含。我們在前幾章裡面偷了一點懶,我們通過包含其它一些標頭檔案,比如qpushbutton.h,這樣就可以間接地包含qwidget.h。
class QSlider;
這裡是另外一個小伎倆,但是沒有前一個用的多。因為我們在類的介面中不需要QSlider,僅僅是在實現中,我們在標頭檔案中使用一個前置的類宣告,並且在.cpp檔案中包含一個QSlider的標頭檔案。
這會使編譯一個大的專案變得更快,因為當一個標頭檔案改變的時候,很少的檔案需要重新編譯。它通常可以給大型編譯加速兩倍或兩倍以上。
class LCDRange : public QVBox
{
Q_OBJECT
public:
LCDRange( QWidget *parent=0, const char *name=0 );
int value() const;
public slots:
void setValue( int );
signals:
void valueChanged( int );
meta object file. 注意Q_OBJECT。這個巨集必須被包含到所有使用訊號和/或槽的類。如果你很好奇,它定義了在元物件檔案中實現的一些函式。
這三個成員函式構成了這個視窗部件和程式中其它元件的介面。直到現在,LCDRange根本沒有一個真正的介面。
value()是一個可以訪問LCDRange的值的公共函式。setValue()是我們第一個自定義槽,並且valueChanged()是我們第一個自定義訊號。
槽必須按通常的方式實現(記住槽也是一個C++成員函式)。訊號可以在元物件檔案中自動實現。訊號也遵守C++函式的保護法則(比如,一個類只能發射它自己定義的或者繼承來的訊號)。
當LCDRange的值發生變化時,valueChanged()訊號就會被使用——你從這個名字中就可以猜到。這將不會是你將會看到的命名為somethingChanged()的最後一個訊號。
t7/lcdrange.cpp這個檔案主要利用了t6/main.cpp,在這裡只是說明一下改變了哪些。
connect( slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)) );
connect( slider, SIGNAL(valueChanged(int)),
SIGNAL(valueChanged(int)) );
這個程式碼來自LCDRange的建構函式。
第一個connect和你在上一篇中看到的一樣。第二個是新的,它把滑塊的valueChanged()訊號和這個物件的valueChanged訊號連線起來了。帶有三個引數的connect()函式連線到this物件的訊號或槽。
是的,這是正確的。訊號可以被連線到其它的訊號。當第一個訊號被髮射時,第二個訊號也被髮射。
讓我們來看看當使用者操作這個滑塊的時候都發生了些什麼。滑塊看到自己的值發生了改變,併發射了valueChanged()訊號。這個訊號被連線到QLCDNumber的display()槽和LCDRange的valueChanged()訊號。
所以,當這個訊號被髮射的時候,LCDRange發射它自己的valueChanged()訊號。另外,QLCDNumber::display()被呼叫並顯示新的數字。
注意你並沒有保證執行的任何順序——LCDRange::valueChanged()也許在QLCDNumber::display()之前或者之後發射,這是完全任意的。
int LCDRange::value() const
{
return slider->value();
}
value()的實現是直接了當的,它簡單地返回滑塊的值。
void LCDRange::setValue( int value )
{
slider->setValue( value );
}
setValue()的實現是相當直接了當的。注意因為滑塊和LCD數字是連線的,設定滑塊的值就會自動的改變LCD數字的值。另外,如果滑塊的值超過了合法範圍,它會自動調節。
LCDRange *previous = 0;
for( int r = 0 ; r < 4 ; r++ ) {
for( int c = 0 ; c < 4 ; c++ ) {
LCDRange* lr = new LCDRange( grid );
if ( previous )
connect( lr, SIGNAL(valueChanged(int)),
previous, SLOT(setValue(int)) );
previous = lr;
}
}
main.cpp中所有的部分都是上一章複製的,除了MyWidget的建構函式。當我們建立16個RCDRange物件時,我們現在使用訊號/槽機制連線它們。每一個的valueChanged()訊號都和前一個的setValue()槽連線起來了。因為當LCDRange的值發生改變的時候,發射一個valueChanged()訊號(驚奇!),我們在這裡建立了一個訊號和槽的“鏈”。
編譯
為一個多檔案的應用程式建立一個makefile和為一個單檔案的應用程式建立一個makefile是沒有什麼不同的。如果你已經把這個例子中的所有檔案都儲存到它們自己的目錄中,你所要做的就是這些:
qmake -project
qmake
第一個命令呼叫qmake來生成一個.pro(專案)檔案。第二個命令根據這個專案檔案來生成一個(系統相關的)makefile。你現在可以輸入make(或者nmake,如果你使用Visual Studio)。
相關文章
- Qt入門(3)——訊號和槽QT
- Qt 5中使用lambda表示式連線訊號和槽QT
- QT從入門到入土(三)——訊號和槽機制QT
- Qt 自動連線機制訊號與槽QT
- 《Qt5:訊號和槽使用示例》QT
- 02_QT訊號和槽QT
- Qt學習第三篇(訊號槽函式的連線)QT函式
- Qt之訊號與槽QT
- Qt Connect 訊號 槽QT
- Qt5的訊號和槽函式QT函式
- Qt 5 中的訊號槽QT
- C++ Qt開發:如何使用訊號與槽C++QT
- PyQT5訊號與槽的連線QT
- Qt 訊號槽傳遞指標QT指標
- Qt訊號與槽使用方法最完整總結QT
- Qt自定義訊號槽的使用淺析+例項QT
- Qt 訊號槽如何傳遞引數(或帶引數的訊號槽)QT
- QT 控制檯訊號與槽簡例QT
- QT學習筆記1(安裝、建立和訊號與槽)QT筆記
- QT槽函式獲取訊號傳送物件QT函式物件
- qt多執行緒訊號槽傳輸方式QT執行緒
- Qt - 訊號與槽的第五個引數QT
- Qt訊號 lamda 表示式使用QT
- Qt 中多執行緒對應的訊號槽QT執行緒
- 《MySQL 入門教程》第 18 篇 連線查詢MySql
- C++《QT之按鍵QPushButton設定訊號與槽》C++QT
- Qt入門(17)——組裝複雜的控制元件QT控制元件
- QT入門QT
- QT中的訊號-槽比我們常用的callback到底牛在哪裡?QT
- C++訊號槽C++
- Qt入門(15)——使用視窗部件QT
- QT快速入門QT
- Qt入門(11)——Qt外掛QT
- [WebGL入門]十一,著色器的編譯和連線Web編譯
- Linux下應用程式開發:QT的訊號與槽機制(轉)LinuxQT
- pl/sql裡的左連線和右連線符號“+”SQL符號
- Qt入門(12)——Qt國際化QT
- Qt入門(13)——Qt的呼叫退出QT