QT-訊號和槽
阿新 • • 發佈:2022-04-06
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() ; }