QT使用教程之信號與槽
1、信號與槽機制介紹
理解:觀察者模式。
信號槽是 Qt 框架引以為豪的機制之一。所謂信號槽,實際就是觀察者模式。當某個事件發生之后,比如,按鈕檢測到自己被點擊了一下,它就會發出一個信號(signal)。這種發出是沒有目的的,類似廣播。如果有對象對這個信號感興趣,它就會使用連接(connect)函數,意思是,將想要處理的信號和自己的一個函數(稱為槽(slot))綁定來處理這個信號。也就是說,當信號發出時,被連接的槽函數會自動被回調。這就類似觀察者模式:當發生了感興趣的事件,某一個操作就會被自動觸發。
2、connect函數+系統自帶的信號和槽
connect(sender, signal, receiver, slot);
參數: 1、信號發出者 2、信號 3、信號的接受者 4、接受到信號執行任務(槽函數)
信號:
void clicked(bool checked = false);
槽函數:
void close();
舉例:點擊窗口內定義的按鈕,關閉窗口
//創建按鈕
QPushButton *button =new QPushButton("點擊關閉窗口",this);
this->resize(600,400);
//信號與槽
connect(button,&QPushButton::clicked,this,&Widget::close);
3、自定義信號與槽
步驟1:確定場景
老師餓了,學生請客
小哥敲門,家人開門
步驟2:添加老師類和學生類
步驟3:在老師類中聲明信號+在學生類中聲明并實現槽函數
teacher.h(信號:一般在signals里面寫,返回值void,參數可以存在,僅聲明不需要實現,可以重載)
signals: void hungury();
student.h(槽函數:一般在public slots里面寫,對于一些高版本的qt來說,也可以寫到public或者全局;返回值void,參數可以存在,需要聲明并實現,可以重載)
public slots: void treat();
student.cpp
#include
void Student::treat(){
qDebug()<<"請老師吃飯";
}
步驟4:創建對象+信號與槽連接
this->tea = new Teacher(this);
this->stu = new Student(this);
connect(tea,&Teacher::hungury,stu,&Student::treat);
步驟5:觸發信號(下課)
widget.h(聲明觸發信號的成員函數)
void ClasOsver();
widget.cpp(定義觸發信號的成員函數+調用該成員函數)
void Widget::ClasOsver(){
emit tea->hungury();
}
補充:信號連接信號
點擊按鈕,請吃飯
方式一:
connect(button,&QPushButton::clicked,this,&Widget::ClasOsver);
方式二:信號連接信號
connect(button,&QPushButton::clicked,tea,&Teacher::hungury);
4、重載自定義信號與槽
步驟1:重新寫信號聲明(帶參數)
void hungury(QString food);
步驟2:重新寫槽函數聲明及定義(帶參數)
void treat(QString food); void Student::treat(QString food){ qDebug()<<"請老師吃飯"<<food; p="" }<="">
步驟3:由于函數重載了,所以需要利用函數指針指向函數地址,然后在做連接
void (Teacher::*teachersignal)(QString) = &Teacher::hungury;
void (Student::*studentslot)(QString) = &Student::treat;
connect(tea,teachersignal,stu,studentslot);
補充:Qt4版本信號槽寫法(了解)
connect(tea,SIGNAL(hungury(QString)),stu,SLOT(treat(QString)));
使用注意:
1、Qt5在語法上是完全兼容4的,反之不可以。
2、如果是Qt4版本的信號與槽寫法,一定要注意信號和槽的名稱不要寫錯。
知識點5:信號與槽總結
自定義信號槽注意事項:
1、發送者與接受者需要是QObject的子類(槽函數全局,lambda除外)
2、信號和槽函數返回值都是void
3、信號需要聲明不需要定義實現,槽函數需要聲明也需要定義實現()。
4、槽函數是普通的成員函數,作為成員函數,會受到 public、private、protected 的影響;
5、使用 emit 在恰當的位置發送信號;
6、使用connect()函數連接信號和槽。
7、任何成員函數、static 函數、全局函數和 Lambda 表達式都可以作為槽函數。
8、信號槽要求信號和槽的參數一致,所謂一致,是參數類型一致。
如果信號和槽的參數不一致,允許的情況是,槽函數的參數可以比信號的少,即便如此,槽函數存在的那些參數的順序也必須和信號的前面幾個一致起來。這是因為,你可以在槽函數中選擇忽略信號傳來的數據(也就是槽函數的參數比信號的少)。
舉例:
signal(QSting)和slot(QSting)√
signal(QSting,QSting)和slot(QSting)√
signal(QSting)和slot(QSting,QSting)×
signal(QSting,QSting,int)和slot(QSting,QSting)√
signal(QSting,QSting,int)和slot(QSting,int)√
拓展:
1、信號與槽對應可以一對一,一對多(發出信號,槽函數一個一個執行,順序不確定),多對一(任意信號發出,槽函數都會執行)
2、信號可以連接信號
3、槽可以被斷開鏈接(disconnect),槽也可以被取消鏈接(當一個對象delete了,取消這個對象上的槽)
4、使用c++11中的lambda表達式。
6、Lambda表達式
概念:C++11中的Lambda表達式用于定義并創建匿名的函數對象,以簡化編程工作。
語法:
[capture](parameters) mutable ->return-type{statement}
1、[capture]捕獲列表,捕獲的是那些到定義Lambda為止時Lambda所在作用范圍內可見的局部變量
2、(parameters)參數列表,與普通函數的參數列表一致的。
3、 mutable可修改標示符,按值傳遞捕獲列表時(默認僅讀權限),加上mutable修飾符后,可以修改按值傳遞進來的拷貝
4、->return-type 返回值類型
5、{statement}函數體,內容跟普通函數一致。
注意:
1、[]標識一個Lambda的開始,這部分必須存在,不能省略。
空 沒有使用任何函數對象參數
= 函數體內可以使用Lambda所在作用范圍內所有可見的局部變量,值傳遞
& 函數體內可以使用Lambda所在作用范圍內所有可見的局部變量,引用傳遞
a 將a按值進行傳遞
&a 將a按引用進行傳遞
this 函數體內可以使用Lambda所在類中的成員變量
a, &b 將a按值進行傳遞,b按引用進行傳遞。
=,&a, &b 除a和b按引用進行傳遞外,其他參數都按值進行傳遞
n &, a, b。除a和b按值進行傳遞外,其他參數都按引用進行傳遞。
2、()參數列表,如果不需要傳遞參數的話,()可以一同省略。
3、如果使用mutable,參數列表()不能省略的即使參數為空;如果使用mutable,修改拷貝,而不是值本身。
4、返回值類型,如果不需要,->return-type都可省略。
5、{函數體},可以使用參數列表,也可以使用捕獲列表。
使用:
1、通過lambda表達式輸入內容
[](){ qDebug()<<"lambda is running!"; }();
等同于
auto fun = [](){ qDebug()<<"lambda is running!"; }; fun();
2、測試參數列表和可修改標示符(如果無mutable,m=300報錯)
int m=10;
auto fun = [m](int a,int b)mutable{ qDebug()<<"lambda is running!"; m=300; return a+b; };
int sum=fun(100,200);
qDebug()<<sum;< p="">
3、槽函數一般可用lambda表達式
QPushButton * myBtn = new QPushButton ("點擊",this);
this->resize(600,400);
connect(myBtn,&QPushButton::clicked,this,[=] () { qDebug() << "按鈕被按下"; } );

相關推薦HOT
更多>>
unity圖集合并成圖片
Unity圖集合并成圖片是一種將多個小圖片合并成一個大圖片的技術。這種技術在游戲開發中非常常見,可以有效地減少內存占用和提高渲染效率。我們...詳情>>
2023-08-28 18:07:44
unity向量旋轉得另一向量
Unity中的向量旋轉是一項常見的操作,可以通過使用旋轉矩陣或四元數來實現。以下是關于如何在Unity中旋轉一個向量得到另一個向量的詳細解釋。在...詳情>>
2023-08-28 18:07:42
unity哪個版本免費
Unity是一款強大的游戲開發引擎,提供了許多功能和工具,可以幫助開發者輕松創建高質量的游戲。關于Unity的版本免費問題,我將為你詳細解答。Un...詳情>>
2023-08-28 18:07:42
unity對象池怎么寫
Unity對象池是一種常用的優化技術,用于管理和重復利用游戲中的對象,以減少內存分配和銷毀的開銷。在Unity中,可以通過編寫一些代碼來實現對象...詳情>>
2023-08-28 18:07:41