Qt筆記之 訊號和槽
阿新 • • 發佈:2020-12-19
訊號和槽
目錄概述
示例程式碼
// mywidget.cpp #include "mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { QPushButton *btn = new QPushButton; btn->setParent(this); // 設定父視窗 btn->setText("點選按鈕關閉視窗"); // 設定文字 resize(600,400); // 重置視窗大小 btn->move(100,100); // 移動按鈕 this->setWindowTitle("訊號和槽"); // 改變視窗標題 this->setFixedSize(600,400); // 固定視窗大小 // 需求:點選按鈕關閉視窗 // 引數1:指標 引數2:訊號(點選) 引數3:指標(本視窗) 引數4:槽函式(關閉視窗) connect(btn,&QPushButton::clicked,this,&MyWidget::close); } MyWidget::~MyWidget() { delete btn; delete btn2; }
自定義訊號和槽
專案結構:
程式碼:
// student.h #ifndef STUDENT_H #define STUDENT_H #include <QObject> class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = nullptr); signals: public slots: // 自定義的槽函式寫在public slots,Qt5後,可以寫在public,全域性和lambda表示式 // 返回值void // 可以有引數,可以過載 // 有宣告,必須有實現 void treat(); }; #endif // STUDENT_H // teacher.h #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(); public slots: }; #endif // TEACHER_H // mywidget.h #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include "student.h" #include "teacher.h" class MyWidget : public QWidget { Q_OBJECT public: MyWidget(QWidget *parent = 0); ~MyWidget(); Teacher *t; Student *s; // 下課函式 void classIsOver(); }; #endif // MYWIDGET_H // student.cpp #include "student.h" #include <QDebug> Student::Student(QObject *parent) : QObject(parent) { } void Student::treat() { qDebug() << "請老師吃飯"; } // mywidget.cpp #include "mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { // 建立具體物件 this->t = new Teacher(this); this->s = new Student(this); // 繫結訊號和槽 connect(t,&Teacher::hungry,s,&Student::treat); classIsOver(); // 下課 } void MyWidget::classIsOver() { // 觸發訊號 emit this->t->hungry(); } MyWidget::~MyWidget() { delete t; delete s; }
效果:
過載
程式碼:
// teacher.h #ifndef TEACHER_H #define TEACHER_H #include <QObject> class Teacher : public QObject { Q_OBJECT public: explicit Teacher(QObject *parent = nullptr); signals: void hungry(); void hungry(QString foodName); public slots: }; #endif // TEACHER_H // student.h #ifndef STUDENT_H #define STUDENT_H #include <QObject> class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = nullptr); signals: public slots: 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) { qDebug() << "請老師吃" << foodName.toUtf8().data(); // 呼叫toUtf8轉為QBtyeArray,再呼叫data轉為char * } // mywidget.cpp #include "mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { // 建立具體物件 this->t = new Teacher(this); this->s = new Student(this); // 繫結訊號和槽 // connect(t,&Teacher::hungry,s,&Student::treat); // 建立有引數的自定義訊號和槽 // 函式指標 -> 函式地址 void(Teacher::*teacherSignal)(QString) = &Teacher::hungry; void(Student::*studentSignal)(QString) = &Student::treat; connect(t,teacherSignal,s,studentSignal); classIsOver(); // 下課 } void MyWidget::classIsOver() { // 觸發訊號 emit this->t->hungry(); emit this->t->hungry("臭豆腐"); } MyWidget::~MyWidget() { delete t; delete s; }
效果:
拓展
#include "mywidget.h"
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
// 建立具體物件
this->t = new Teacher(this);
this->s = new Student(this);
// 繫結訊號和槽
// 無參訊號和槽函式
void(Teacher::*teacherNoSignal)() = &Teacher::hungry;
void(Student::*studentNoSignal)() = &Student::treat;
connect(t,teacherNoSignal,s,studentNoSignal);
// 建立有引數的自定義訊號和槽
// 函式指標 -> 函式地址
void(Teacher::*teacherSignal)(QString) = &Teacher::hungry;
void(Student::*studentSignal)(QString) = &Student::treat;
connect(t,teacherSignal,s,studentSignal);
// 點選按鈕下課
QPushButton *btn = new QPushButton;
btn->setParent(this);
btn->setText("下課!");
// 訊號連線訊號
connect(btn,&QPushButton::clicked,s,studentNoSignal);
// 拓展
// 1. 訊號可以連線訊號
// 2. 訊號和槽可以斷開連線disconnect
// 3. 多個訊號可以連線同一個槽函式
// 4. 一個訊號可以連線多個槽函式
// 5. 訊號和槽的引數型別必須一一對應
// 6. 訊號引數的個數可以多於槽函式,反之不可以(很重要)
}
void MyWidget::classIsOver() {
// 觸發訊號
emit this->t->hungry();
emit this->t->hungry("臭豆腐");
}
MyWidget::~MyWidget()
{
delete t;
delete s;
delete btn;
}