卓越 網(wǎng)站建設(shè) 深圳西鄉(xiāng)競價托管
QT信號和槽與自定義的信號和槽
1.概述
這篇文章介紹下QT信號和槽的入門知識,通過一個案例介紹如何創(chuàng)建信號和槽,并調(diào)用他們。
2.信號和槽使用
下面通過點擊按鈕關(guān)閉窗口的案例介紹如何使用信號和槽。
- 創(chuàng)建按鈕
在widget.cpp文件中創(chuàng)建按鈕代碼如下
#include "mywidget.h"
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent)
{// 第二種創(chuàng)建按鈕方式QPushButton *btn2 = new QPushButton("構(gòu)造按鈕",this);
- 使用信號和槽實現(xiàn)點擊按鈕關(guān)閉窗口
使用QObject類中的connect函數(shù)連接信號和槽,該函數(shù)需要4個參數(shù)- 參數(shù)1: 發(fā)送者,誰發(fā)送信號——btn2
- 參數(shù)2: 發(fā)送的是什么信號,信號用函數(shù)地址——&QPushButton::clicked
- 參數(shù)3: 接受者,誰來接受信號——this指的是當前窗口對象
- 參數(shù)4: 槽,接受者做出的動作——&QWidget::close
connect(btn2, &QPushButton::clicked, this, &QWidget::close);
3.如何查看QT提供的信號和槽函數(shù)
在使用connect連接信號和槽的時候,第一個參數(shù)發(fā)送者是btn2按鈕對象,屬于QPushButton類。
如何查看系統(tǒng)提供的信號?
第二個參數(shù)需要知道發(fā)送什么信號,這個時候怎么知道QPushButton提供了哪些信號那,這就需要查看QT幫助文檔。
首先在編輯器中點擊HELP
打開幫助文檔,輸入QPush查看QPushButton
中提供的內(nèi)容沒有Signal
信號。
接著查看QPushButton
父類
在父類中看到有Signals
信號,點擊它,跳轉(zhuǎn)到信號介紹位置。
在信號介紹中給出了所有的信號,我們選擇第一個就是我們示例中的點擊信號。在使用這個信號函數(shù)時候一定要用地址引用方式調(diào)用它,就是在調(diào)用前加上&
符號。
connect(btn2, &QPushButton::clicked, this, &QWidget::close);
如何查看系統(tǒng)提供的槽?
查看方法和上面查看信號一樣,我們是關(guān)閉窗口,窗口的類是QWidge
,查看它的槽中提供了close()
函數(shù)。
connect(btn2, &QPushButton::clicked, this, &QWidget::close);
3.自定義信號和槽功能
上面介紹的是使用QT提供的信號和槽,下面通過一個實例介紹如何自定義自己的信號和槽的功能。
示例功能描述
老師類發(fā)出一個下課的信號,學生類的槽執(zhí)行請客吃飯
- 新建項目
首先新建一個QWidge
類型項目,然后在項目名稱上右鍵,新建clss文件,名稱輸入
Teacher
。然后再新建另一個class文件,名稱輸入Student
。
2. 創(chuàng)建信號
在teacher.h
文件中創(chuàng)建信號, 信號只需要定義不需要實現(xiàn)。
#ifndef TEACHER_H
#define TEACHER_H#include <QObject>class Teacher : public QObject
{Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);signals:/* 自定義信號,寫到signals中* 返回值是void,只需要聲明不需要實現(xiàn)* 可以有參數(shù),可以重載*/void hungry();};#endif // TEACHER_H
- 創(chuàng)造槽
在student.h
文件中創(chuàng)建槽函數(shù),槽函數(shù)聲明后需要在student.cpp
文件中實現(xiàn)功能。
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);signals:public slots:/* 早起QT版本,必須寫到public slots, 高級版本可以寫到public或者全局中* 返回值void, 需要聲明并且實現(xiàn)* 可以有參數(shù),可以重載
*/void treat();};#endif // STUDENT_H
在student.cpp
文件中實現(xiàn)功能
#include "student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent)
{}void Student::treat()
{qDebug() << "執(zhí)行槽函數(shù),請客吃飯";
}
- 連接信號和槽
在QWidget.h
文件中創(chuàng)建Teacher和Student類對象,創(chuàng)建一個觸發(fā)下課的函數(shù)。
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "teacher.h"
#include "student.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
// 創(chuàng)建Teacher和Student類對象Teacher *tc;Student *st;private:Ui::Widget *ui;
// 創(chuàng)建一個觸發(fā)下課的函數(shù)void classIsDown();
};
#endif // WIDGET_H
在QWidget.cpp
文件中實現(xiàn)信號和槽的功能
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 1.創(chuàng)建對象this->tc = new Teacher(this);this->st = new Student(this);
// 2.連接信號和槽connect(tc, &Teacher::hungry, st, &Student::treat);
// 3.調(diào)用觸發(fā)下課函數(shù)classIsDown();
}//4.下課函數(shù)使用emit發(fā)送信號
void Widget::classIsDown()
{emit tc->hungry();
}
Widget::~Widget()
{delete ui;
}
4.信號和槽函數(shù)重載
當我們自定義信號和槽函數(shù)時,他們可以通過參數(shù)進行重載,實現(xiàn)更多的功能。當使用重載時,調(diào)用的時候需要使用函數(shù)指針指向函數(shù)地址,確認調(diào)用哪個重載的函數(shù)。
繼續(xù)使用上面的示例,在Teacher和Student類中添加重載的信號和槽
- 添加重載的信號
在teacher.h文件中新增void hungry(QString foodName);
有參的信號
#ifndef TEACHER_H
#define TEACHER_H#include <QObject>class Teacher : public QObject
{Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);signals:/* 自定義信號,寫到signals中* 返回值是void,只需要聲明不需要實現(xiàn)* 可以有參數(shù),可以重載*/void hungry();
// 信號參數(shù)重載void hungry(QString foodName);};#endif // TEACHER_H
- 添加重載的槽
在student.h文件中添加void treat(QString foodName);
槽函數(shù)
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);signals:public slots:/* 早起QT版本,必須寫到public slots, 高級版本可以寫到public或者全局中* 返回值void, 需要聲明并且實現(xiàn)* 可以有參數(shù),可以重載
*/void treat();// 槽參數(shù)重載void treat(QString foodName);};#endif // STUDENT_H
在student.cpp文件中實現(xiàn)槽函數(shù)功能
#include "student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent)
{}void Student::treat()
{qDebug() << "執(zhí)行槽函數(shù),請客吃飯";
}void Student::treat(QString foodName)
{qDebug() << "執(zhí)行參數(shù)重載的槽函數(shù),吃" << foodName.toUtf8().data();
}
- 調(diào)用重載的信號和槽函數(shù)
在widget.cpp文件中通過connect()函數(shù)調(diào)用信號和槽之前需要先指明調(diào)用的是有參的信號和槽函數(shù),方法如下
// 調(diào)用有參的信號和槽
// 1.聲明一個函數(shù)指針,指向函數(shù)地址void(Teacher::*teacherSignal) (QString) = &Teacher::hungry;void(Student::*studentSlot)(QString) = &Student::treat;
// 2.連接信號和槽connect(tc, teacherSignal, st, studentSlot);
完整代碼
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 1.創(chuàng)建對象this->tc = new Teacher(this);this->st = new Student(this);
// 2.連接信號和槽
// connect(tc, &Teacher::hungry, st, &Student::treat);
// 3.調(diào)用觸發(fā)下課函數(shù)
// classIsDown();// 調(diào)用有參的信號和槽
// 1.聲明一個函數(shù)指針,指向函數(shù)地址void(Teacher::*teacherSignal) (QString) = &Teacher::hungry;void(Student::*studentSlot)(QString) = &Student::treat;
// 2.連接信號和槽connect(tc, teacherSignal, st, studentSlot);
// 3.調(diào)用觸發(fā)下課函數(shù)classIsDown();
}//4.下課函數(shù)使用emit發(fā)送信號
void Widget::classIsDown()
{
// 調(diào)用無參信號
// emit tc->hungry();
// 調(diào)用有參信號emit tc->hungry("糖醋里脊");
}
Widget::~Widget()
{delete ui;
}
5.信號連接信號
上面觸發(fā)信號使用的是emit,如果我們想實現(xiàn)通過點擊按鈕來觸發(fā)信號,那么可以采用普通的按鈕發(fā)送信號控制槽函數(shù),還可以采用信號連接信號實現(xiàn)。
// 點擊按鈕觸發(fā)下課,第一種方式通過信號和槽實現(xiàn)。QPushButton *btn = new QPushButton("下課",this);this->resize(600,400);
// connect(btn, &QPushButton::clicked, this, &Widget::classIsDown);// 點擊按鈕觸發(fā)下課,第二種通過信號連接信號實現(xiàn)void(Teacher::*teacherSignal2) (void) = &Teacher::hungry;void(Student::*studentSlot2)(void) = &Student::treat;connect(tc, teacherSignal2, st, studentSlot2);// 通過一個按鈕信號,鏈接到上面Teacher的信號,觸發(fā)上面的信號和槽執(zhí)行
// 當點擊按鈕時,按鈕發(fā)送信號給teacher的信號,teacher信號被觸發(fā)就會發(fā)送信號給student槽函數(shù)connect(btn, &QPushButton::clicked, tc, teacherSignal2);
6.斷開信號
使用disconnect函數(shù)斷開信號,函數(shù)中的參數(shù)就是要斷開鏈接connect里面的參數(shù)。
// 點擊按鈕觸發(fā)下課,第二種通過信號連接信號實現(xiàn)void(Teacher::*teacherSignal2) (void) = &Teacher::hungry;void(Student::*studentSlot2)(void) = &Student::treat;connect(tc, teacherSignal2, st, studentSlot2);// 通過一個按鈕信號,鏈接到上面Teacher的信號,觸發(fā)上面的信號和槽執(zhí)行connect(btn, &QPushButton::clicked, tc, teacherSignal2);// 斷開信號disconnect(tc, teacherSignal2, st, studentSlot2);
7.擴展
- QT4版本信號和槽寫法
// QT4版本信號和槽connect(tc,SIGNAL(hungry()), st, SLOT(treat()));