當前位置:
首頁 >
Qt信号和槽
發布時間:2023/12/20
48
豆豆
#include "mywidget.h"
#include "qpushbutton.h"myWidget::myWidget(QWidget *parent): QWidget(parent)
{//創建按鈕QPushButton *btn=new QPushButton();btn->setParent(this); //show方法顯示的是頂層窗口 btn的show方法會把btn單獨顯示在窗口外面btn->setText("第一個按鈕");//需求 點擊按鈕關閉窗口connect(btn, //信號的發送者&QPushButton::clicked, //發送的信號 //這里只能使用QPushButton 而不能使用實例化對象btnthis, //信號的接收者 //信號接收者可以是一個類 &myWidget::close //處理的槽函數);//設置窗口標題setWindowTitle("第一個QT程序");
}myWidget::~myWidget()
{}
connect函數把按鈕的點擊事件和窗口的處理函數close關聯了起來。
需要注意的是:發送的信號函數的參數個數一定要比槽函數的參數多,且類型一樣,否則會報錯.
自定義信號和槽
1:信號函數的編寫
signals://自定義信號 寫道signals下//返回值時 void 只需要申明 不需要實現//可以有參數 可以重載void hungry();2:槽函數的編寫
.h類定義 public slots://qt5.0以后 槽函數可以寫在public下,也可以是全局函數//返回值void 需要申明 也需要實現//可以有參數 可以重載void treat(); };.cpp類實現 void Student::treat() {qDebug()<<"請老師吃飯"; }3:使用connect連接
connect(yxp,&Teacher::hungry,ly,&Student::treat);4:發射信號
也就是調用到hungry函數
自定義的信號和槽發生重載的解決
當信號函數或者槽函數有重載的情況時,在connect時,需要定義函數指針的方式明確是哪一個重載函數。
例如:
#ifndef TEACHER_H #define TEACHER_H#include <QObject>class Teacher : public QObject {Q_OBJECT public:explicit Teacher(QObject *parent = nullptr);signals://自定義信號 寫道signals下//返回值時 void 只需要申明 不需要實現//可以有參數 可以重載void hungry();void hungry(QString); //在這里有重載的情況 public slots: };#endif // TEACHER_H #ifndef STUDENT_H #define STUDENT_H#include <QObject>class Student : public QObject {Q_OBJECT public:explicit Student(QObject *parent = nullptr);signals://自定義信號 寫道signals下//返回值時 void 只需要申明 不需要實現//可以有參數 可以重載 public slots://qt5.0以后 槽函數可以寫在public下,也可以是全局函數//返回值void 需要申明 也需要實現//可以有參數 可以重載void treat();void treat(QString foodName); };#endif // STUDENT_H// 構造函數的實現在cpp中 void Student::treat() {qDebug()<<"請老師吃飯"; }void Student::treat(QString foodName) {qDebug()<<"請老師吃飯,老師要吃"<<foodName.toUtf8().data(); }窗口類包含測試的兩個類指針
#ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include "teacher.h" #include "student.h" class myWidget : public QWidget {Q_OBJECTprivate:Teacher *yxp;Student *ly; public:myWidget(QWidget *parent = 0);void clasIsOver();~myWidget(); };#endif // MYWIDGET_H在窗口類的構造函數中,實現的發射信號
#include "mywidget.h" #include "qpushbutton.h"myWidget::myWidget(QWidget *parent): QWidget(parent) {//創建一個老師對象this->yxp=new Teacher(this);//創建一個學生對象this->ly=new Student(this);//定義函數指針 重載時就必須這樣指明要調用的是哪一個函數void (Teacher::*teacherSingal)(QString)=&Teacher::hungry;void (Student::*studentSlot)(QString)=&Student::treat;connect(yxp,teacherSingal,ly,studentSlot);clasIsOver(); }void myWidget::clasIsOver() {//emit 代表要發射信號了 是一個宏定義 為空emit yxp->hungry("魚香肉絲"); }myWidget::~myWidget() {}信號連接信號
創建一個按鈕,點擊按鈕發送信號,在這里用類的成員函數當成槽函數.
myWidget::myWidget(QWidget *parent): QWidget(parent) {//創建一個老師對象this->yxp=new Teacher(this);//創建一個學生對象this->ly=new Student(this);//定義函數指針void (Teacher::*teacherSingal)(void)=&Teacher::hungry;void (Student::*studentSlot)(void)=&Student::treat;connect(yxp,teacherSingal,ly,studentSlot);QPushButton *btn=new QPushButton("點擊觸發信號",this);this->resize(600,400);//信號連接信號,這里使用沒有參數的teacherSingal是因為QPushButton::clicked的參數為bool類型.而我們自己定義的信號teacherSingal有參數是QString的.//會產生類型不匹配的問題 ,這里值得注意connect(btn,&QPushButton::clicked,yxp,teacherSingal);}信號斷開連接
關閉指定對象的所有信號
disconnect(myObject, 0, 0, 0);等同于下面的寫法
myObject->disconnect();關閉指定信號的所有連接
disconnect(myObject, SIGNAL(mySignal()), 0, 0);等同于下面的寫法
myObject->disconnect(SIGNAL(mySignal()));斷開指定的接收者的連接
disconnect(myObject, 0, myReceiver, 0);等同于下面的寫法
myObject->disconnect(myReceiver);Lambda表達式
c++11中的Lambda表達式用于定義并創建匿名的函數對象,以簡化編程工作
[函數對象參數](操作符重載函數參數)mutable->返回值{函數體}[]:函數對象參數標志一個Lambda的開始,這部分必須存在不能省略.
空: 沒有使用任何函數對象參數
=:函數體內可以使用Lambda所在作用范圍內所有課件的局部變量,(包括Lambda所在類的this),并且是值傳遞方式,所有的局部變量都是只讀,不可以修改的.
3)&:函數體內可以使用Lambda所在作用范圍內所有課件的局部變量,(包括Lambda所在類的this),并且是引用傳遞方式,修改傳過來的值,會影響原來的局部變量.可以修改外部傳過來的局部變量.
4)a :把局部變量a按值傳入函數體中,函數體中只能使用該變量
5)&a :把局部變量a引用傳遞到函數體中,函數體中只能使用該變量,可以修改該變量的值,外部也會改變.
6)mutable:該關鍵字的作用是表明可以修改按值傳遞進來的拷貝,而不是值本身.(內部修改,不影響外部),
myWidget::myWidget(QWidget *parent): QWidget(parent) {QPushButton *btn=new QPushButton("點擊觸發信號",this);this->resize(600,400);[=](){btn->setText("修改按鈕");}();//最后加的(),代表調用一次匿名函數 }在connect函數中使用Lambda表達式
//connect函數最后一個參數可以使用Lambda表達式,更加易于傳參數進去,因為有時候信號會限制槽函數的參數類型及個數.//而使用Lambda表達式完美的解決了這個問題connect(btn,&QPushButton::clicked,this,[=](){ emit clasIsOver();});返回值
int ret=[]()->int{return 0;}(); //->int 表明返回值是int類型總結
- 上一篇: Tian Ji -- The Horse
- 下一篇: 金蝶云星空与巨益OMS对接集成采购退料查