1. 程式人生 > 其它 >QT-訊號和槽

QT-訊號和槽

 main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

  wedget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "teacher.h"
#include "student.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;

    Teacher * zt;
    Student * st;

    void classIsOver();

};

#endif // WIDGET_H

   wedget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
//Teacher 類  老師類
//Student 類  學生類
//下課後 ,老師會觸發一個訊號,餓了 ,學生響應訊號,請客吃飯

void func()
{
    qDebug() <<"aaa";

}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //建立一個老師物件
    this->zt = new Teacher(this);

    //建立一個學生物件
    this->st = new Student(this);


//    //老師餓了 學生請客的連線
//    connect(zt,&Teacher::hungry,st,&Student::treat);

//    //呼叫下課函式
//    classIsOver();


    //連線帶引數的 訊號和槽
    //指標 -> 地址
    // 函式指標 -> 函式地址

    void(Teacher:: *teacherSignal)(QString  ) = &Teacher::hungry;
    void(Student:: *studentSlot)(QString  )  = &Student::treat;
    connect(zt,teacherSignal,st,studentSlot);
   // classIsOver();


    //點選一個 下課的按鈕 ,再觸發下課
    QPushButton * btn = new QPushButton("下課",this);
    //重置視窗大小
    this->resize(600,400);

    //點選按鈕 觸發下課
    //connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);


    //無參訊號和槽連線
    void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;
    void(Student:: *studentSlot2)(void)  = &Student::treat;
    //connect(zt,teacherSignal2,st,studentSlot2);

    //訊號連線訊號
    connect(btn,&QPushButton::clicked, zt, teacherSignal2);

    //斷開訊號
    //disconnect(zt,teacherSignal2,st,studentSlot2);

    //拓展
    //1、訊號是可以連線訊號
    //2、一個訊號可以連線多個槽函式
    //3、多個訊號 可以連線 同一個槽函式
    //4、訊號和槽函式的引數 必須型別一一對應
    //5、訊號和槽的引數個數  是不是要一致?訊號的引數個數 可以多餘槽函式的引數個數

    //Qt4版本以前的訊號和槽連線方式
    //利用Qt4訊號槽 連線無參版本
    //Qt4版本 底層SIGNAL("hungry")  SLOT( "treat")
    connect(zt,SIGNAL(hungry()) , st , SLOT(treat()));
    //Qt4版本優點:引數直觀,缺點 :型別不做檢測
    //Qt5以上  支援 Qt4的版本寫法,反之不支援

//    QPushButton * btn2 = new QPushButton;

//    [btn](){
//        btn->setText("aaaa");
//        btn2->setText("bbb"); //btn2看不到
//    }();


    // mutable關鍵字 用於修飾值傳遞的變數,修改的是拷貝,而不是本體

//    QPushButton * myBtn = new QPushButton (this);
//    QPushButton * myBtn2 = new QPushButton (this);
//    myBtn2->move(100,100);
//    int m = 10;

//    connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });

//    connect(myBtn2,&QPushButton::clicked,this,[=] ()  { qDebug() << m; });

//    qDebug() << m;


//    int ret = []()->int{return 1000;}();
//    qDebug() << "ret = " << ret ;



    //利用lambda表示式 實現點選按鈕 關閉視窗
    QPushButton * btn2 = new QPushButton ;
    btn2->setText("關閉");
    btn2->move(100,0);
    btn2->setParent(this);
    connect(btn2,&QPushButton::clicked, [=](){
//        this->close();
//        emit zt->hungry("宮保雞丁");

        btn2->setText("aaaa");
    });


    //lambda表示式 最常用  [=](){}



}

void Widget::classIsOver()
{
    //下課函式,呼叫後 觸發老師餓了的訊號
    //emit zt->hungry();
    emit zt->hungry("宮保雞丁");
}

Widget::~Widget()
{
    delete ui;
}

   teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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


signals:
    //自定義訊號  寫到signals下
    //返回值是void ,只需要宣告,不需要實現
    //可以有引數,可以過載
    void hungry();

    void hungry(QString foodName);

public slots:

};

#endif // TEACHER_H

    teacher.cpp

#include "teacher.h"

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

}

     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:
    //早期Qt版本 必須要寫到public slots,高階版本可以寫到 public或者全域性下
    //返回值 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()<< "請老師吃飯";
}


void Student::treat(QString foodName)
{
    //QString -> char * 先轉成 QByteArray  ( .toUtf8() ) 再轉char * ( .data() )
    qDebug() << "請老師吃飯,老師要吃:" << foodName.toUtf8().data() ;
}