信號槽機制和自定義信號和槽

信號槽和機制

情景帶人:

我們都知道鴻門宴,其中項羽想要殺劉邦,就在洪門設宴,並和手下兄弟約定只要項羽摔杯,就從進去綁了劉邦;
在這裏插入圖片描述

建立:信號和槽函數的關係使用connect

connect(信號的發起者,信號,接受者,操作);

案例:

widget的構造函數中:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //設置窗口標題
    this->setWindowTitle("信號");
    //設置窗口大小
    this->resize(800,600);
    //創建一個按鈕
    QPushButton *btn1=new QPushButton("關閉",this);
    //需求:單擊btn1 關閉主窗口
    //信號的發起者btn1 發出信號   主窗口this  關閉(槽函數)
    connect(btn1, &QPushButton::clicked, this, &QWidget::close);


    //lambda表達式
    QPushButton *btn2 =new QPushButton("戳我呀",this);
    btn2->move(400,300);
    connect(btn2, &QPushButton::clicked, [=](){
        //獲取按鈕上的文本
        QString text = btn2->text();
        qDebug()<<text <<endl;

        //設置按鈕的文本
        btn2->setText("戳你咋地?");
    } );
}

運行結果:
在這裏插入圖片描述

自定義信號和槽(瞭解)

老師—>餓了信號 學生—>請老師喫飯
設計兩個類:老師類 學生類

注意:

1、定義信號的規則:在signals下方返回值類型爲void 只需聲明 不用實現 可以有參數 可以重載

2、定義槽函數的規則:public slots:返回值類型爲void 需要聲明 需要實現 可以有參數 可以重載

3、用戶可以使用emit 發出信號

emit tea->hungry();

在這裏插入圖片描述

案例:

student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = 0);

signals:

public slots:
    //返回值類型爲void  需要聲明 需要實現  可以有參數 可以重載
    void treat();
    void treat(QString foodName);
};

#endif // STUDENT_H

student.cpp

#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::treat()
{
    qDebug()<<"請老師喫飯了"<<endl;
}

void Student::treat(QString foodName)
{
    qDebug()<<"請老師喫飯了"<<foodName<<endl;
}

teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>
#include<QString>
class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = 0);

signals://自定義信號函數
    //定義信號的規則:返回值類型void 只需聲明  不用實現  可以有參數 可以重載
    void hungry();
    void hungry(QString foodName);
public slots://自定義槽函數
};

#endif // TEACHER_H

teacher.cpp

#include "teacher.h"

Teacher::Teacher(QObject *parent) : QObject(parent)
{
}

widget構造函數:

#include "widget.h"
#include"teacher.h"
#include"student.h"
#include<QPushButton>
#define N 0
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //設置主窗口大小
    this->resize(800,600);
    //實例化一個老師
    Teacher *tea = new Teacher(this);
    //實例化一個學生
    Student *stu = new Student(this);
#if N
    //connect建立老師和學生的關係
    void (Teacher:: *p1)() = &Teacher::hungry;
    void (Student:: *p2)() = &Student::treat;
    connect(tea,p1, stu, p2);
#else
    //報錯的原因:hungry信號被重載了
    //通過函數指針 明確那個信號
    void (Teacher:: *p1)(QString foodName) = &Teacher::hungry;
    void (Student:: *p2)(QString foodName) = &Student::treat;
    connect(tea,p1, stu, p2);
#endif
    //下課了 老師餓了
    QPushButton *btn = new QPushButton("下課", this);
    connect(btn,&QPushButton::clicked,[=](){
#if N
        //下課函數:讓老師發出餓的信號
        emit tea->hungry();
#else
        //下課函數:讓老師發出餓的信號
        emit tea->hungry("鍋包肉");
#endif
    });
    
}

Widget::~Widget()
{

}

在這裏插入圖片描述

總結:

1、一個信號可以和多個槽相連

如果是這種情況,這些槽會一個接一個的被調用,但是它們的調用順序是不確定的。

2、多個信號可以連接到一個槽

只要任意一個信號發出,這個槽就會被調用。

3、一個信號可以連接到另外的一個信號

當第一個信號發出時,第二個信號被髮出。除此之外,這種信號-信號的形式和信號-槽的形式沒有什麼區別。

4、槽可以被取消鏈接

這種情況並不經常出現,因爲當一個對象delete之後,Qt自動取消所有連接到這個對象上面的槽。

5、Qt4版本的信號槽寫法

connect(tea,SIGNAL(hungry()), stu, SLOT(treat()));

6、Qt5版本的信號槽寫法

connect(tea, &Teacher::hungry, stu, &Student::treat);

綜合案例(窗口切換)

在這裏插入圖片描述

創建一個窗口類:

類名爲:swidget
在這裏插入圖片描述
在這裏插入圖片描述
swidget.h

#ifndef SWIDGET_H
#define SWIDGET_H

#include <QWidget>

class SWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SWidget(QWidget *parent = 0);

signals:
    void back();//回退信號
public slots:
};

#endif // SWIDGET_H

swidget.cpp

#include "swidget.h"
#include<QPushButton>
SWidget::SWidget(QWidget *parent) : QWidget(parent)
{
    //設置查詢窗口的大小
    this->resize(800,600);
    this->setWindowTitle("查詢窗口");

    //定義一個回退按鈕
    QPushButton *btn = new QPushButton("back",this);

    //當按下back 就發出一個back信號
    connect(btn,&QPushButton::clicked,[=](){
        emit this->back();
    });
}

widget.cpp

#include "widget.h"
#include <QPushButton>
#include"swidget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->resize(800,600);
    this->setWindowTitle("登錄");

    //定義一個查詢窗口
    SWidget *s = new SWidget();

    //創建一個下一頁的按鈕
    QPushButton *btn = new QPushButton("下一頁",this);
    connect(btn,&QPushButton::clicked,[=](){
        //當前窗口隱藏
        this->hide();
        //查詢窗口顯示
        s->show();
    });

    //監測查詢窗口s的回退信號
    connect(s,&SWidget::back,[=](){
        //隱藏查詢窗口
        s->hide();
        //顯示當前窗口
        this->show();
    });

}

Widget::~Widget()
{

}

運行結果:
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章