-
概念
信号和槽是Qt中自行定義一種通信機制,實作對象之間的互動;當對象的狀态發生改變,将會發送信号,該信号可以被其它對象所接收,接收到信号後會執行一個指定操作函數(槽)。
- 定義
class XX:public QObject{ Q_OBJECT //moc元對象編譯器 signals: void sig_func(...);//信号 public slots: void slot_func(...){...}//槽 };
注:信号函數隻需聲明,不能寫定義
注:槽函數可以連接配接到某個信号上,通過信号可以觸發槽函數的執行;另外槽函數也可以當做一個普通成員函數,直接調用.
- 信号和槽連接配接
QObject::connect( const QObject* sender,//信号發送對象 const char* signal, //信号函數 const QObject* receiver,//信号的接收對象 const char* method)//槽函數
SIGNAL(信号函數(參數表))//将信号函數轉換為const char*
SLOT(槽函數(參數表))//将槽函數轉換為const char*
案例:建立Qt應用程式,裡面包含一個标簽(QLabel)和一個按鈕(QPushButton),實作點選按鈕關閉标簽功能.
#include <QApplication> #include <QLabel> #include <QPushButton> #include <QFont> #include <QDialog> int main(int argc,char** argv){ QApplication app(argc,argv); QDialog parent;//父視窗 parent.resize(480,320); //建立按鈕和标簽控件 QPushButton button("關閉标簽",&parent); QLabel label("我是标簽",&parent); //調整大小和位置 button.move(50,200); label.move(50,50); button.resize(150,50); label.resize(150,50); //設定字型大小 QFont font; font.setPointSize(20); parent.setFont(font); //動态建立按鈕對象 QPushButton* button2 = new QPushButton("退出",&parent); button2->move(300,200); button2->resize(150,50); //顯示父視窗 parent.show(); //點選按鈕關閉标簽 QObject::connect( &button,SIGNAL(clicked(void)), &label,SLOT(close(void))); //練習:使用new操作動态建立一個按鈕對象,文本顯 //示"退出",實作點選該按鈕退出應用程式功能. QObject::connect( button2,SIGNAL(clicked(void)), //&app,SLOT(closeAllWindows(void))); &app,SLOT(quit(void))); //&parent,SLOT(close(void))); return app.exec(); }
-
信号和槽連接配接的文法要求
1)信号和槽參數要一緻
2)可以有預設參數QObject::connect(A,SIGNAL(sigfun(int)), B,SLOT(slotfun(int)));//ok QObject::connect(A,SIGNAL(sigfun(void)), B,SLOT(slotfun(int)));//error
3)信号的參數可以多于槽,多餘參數将被忽略class B:public QObject{ Q_OBJECT public slots: void slotfun(int = 0){} }; QObject::connect(A,SIGNAL(sigfun(void)), B,SLOT(slotfun(void)));//ok
4)一個信号可以同時連接配接多個槽(一對多)QObject::connect(A,SIGNAL(sigfun(int)),B,SLOT(slotfun(void)));//ok
QObject::connect(A,SIGNAL(sigfun(int)),B1,SLOT(slotfun1(int)));
QObject::connect(A,SIGNAL(sigfun(int)),B2,SLOT(slotfun2(int)));
注:當A發送信号,B1和B2的槽函數都将被執行,但是多線程下執行順序不确定.
5)多個信号可以同時連接配接同一個槽(多對1)
QObject::connect(A1,SIGNAL(sigfun1(int)), B,SLOT(slotfun(int)));
QObject::connect(A2,SIGNAL(sigfun2(int)), B,SLOT(slotfun(int)));
注:無論A1還是A2發送信号,B的槽函數都會被執行
6)兩個信号可以直接連接配接(信号串聯)
QObject::connect(A1,SIGNAL(sigfun1(int)), A2,SIGNAL(sigfun2(int)));
A1–A2–>B
注:如果A1發送信号,A2的信号也将随之發送
案例:事件同步,實作滑塊(QSlider)和選值框(QSpinBox)同步運作
1)滑塊:QSlider
QSlider(垂直/水準,父視窗指針);//構造函數
void setRange(int min,int max);//設定滑動範圍
void valueChanged(int value);//滑塊滑動時發送的信号
void setValue(int value);//設定目前滑塊位置槽函數
2)選值框:QSpinBox
QSpinBox(父視窗指針);//構造函數
void setRange(int min,int max);//設定選值框數值範圍
void valueChanged(int value);//數值改變時發送的信号
void setValue(int value);//設定目前目前數值槽函數
#include <QApplication> #include <QSlider>//滑塊 #include <QSpinBox>//選值框 #include <QDialog> #include <QFont> int main(int argc,char** argv){ QApplication app(argc,argv); //父視窗 QDialog parent; parent.resize(480,320); QFont font; font.setPointSize(20); parent.setFont(font); //滑塊 QSlider slider(Qt::Horizontal,&parent); slider.setRange(1,100); slider.move(100,50); //選值框 QSpinBox spin(&parent); spin.setRange(1,100); spin.move(100,200); //顯示父視窗 parent.show(); //滑塊滑動,選值框數值随之改變 QObject::connect( &slider,SIGNAL(valueChanged(int)), &spin,SLOT(setValue(int))); //選值框數值改變,滑塊随之滑動 QObject::connect( &spin,SIGNAL(valueChanged(int)), &slider,SLOT(setValue(int))); return app.exec(); }
注意以上代碼編譯時要按照qmake -project qmeke make …