Qt学习之旅 -信号与槽

点击关闭窗口

connect(信号发送者,发送的具体信号,信号接收者,型号的处理(槽slot));

这里自定义的MyPushButtonQPushButton别无二至

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    
    
    resize(600,400);
    setWindowTitle("第一个窗口");
    setFixedSize(600,400);
    //创建一个按钮
    MyPushButton *myBtn = new MyPushButton;
    myBtn->setText("我自己的按钮");
    myBtn->setParent(this);
    myBtn->move(0,20);

    //需求: 点击我的按钮 关闭窗口
    connect(myBtn,&QPushButton::clicked, this,&Widget::close);
}

自定义信号和槽

在这里插入图片描述

//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

//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:
    //早期Qt版本 必须要写到public slots,高级版本可以写到public或者全局下
    //返回值void,需要声明,也需要实现
    //可以有参数,可以发生重载
    void treat(); //申明
};

#endif // STUDENT_H

#include "student.h"
#include <QDebug>

Student::Student(QObject *parent) : QObject(parent)
{
    
    

}

void Student::treat(){
    
    
  //实现
    qDebug() << "请老师吃饭";
}

//widget.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 *stu;

	void classIsOver();
};

#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"



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

    //创建一个老师对象
    this->zt = new Teacher(this);
    //创建一个学生对象
    this->stu = new Student(this);
    //老师触发一个信号:饿了;学生响应信号:请客吃饭
    connect(zt,&Teacher::hungry,stu,&Student::treat);
    //调用下课函数
    classIsOver();
}

void Widget::classIsOver(){
    
    
    //触发信号
    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 = 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;
}

#include "widget.h"
#include "ui_widget.h"



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

    //创建一个老师对象
    this->zt = new Teacher(this);
    //创建一个学生对象
    this->stu = new Student(this);
    //连接带参数的信号和槽
    //指针 -> 地址
    //函数指针 -> 函数地址
    void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;//指向有参数的那个
    void(Student:: *studentSlot)(QString) = &Student::treat; //指向有参数的那个
    connect(zt,teacherSignal,stu,studentSlot);
    //调用下课函数
    classIsOver();
}
void Widget::classIsOver(){
    
    
    //触发信号
    emit zt->hungry("红烧牛肉");
}

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

需要通过函数指针告诉它找哪块函数定义(有参还是无参)

在这里插入图片描述
这里不是有""引起了要吃的东西(就是"红烧牛肉")

//Student.cpp
void Student::treat(QString foodName){
    
    
    qDebug() << "请老师吃饭,老师要吃" << foodName.toUtf8().data();
}

重点: 需要利用函数指针明确指向函数的地址void(类名:: *实例名)(QString/*形参*/) = 类名::重载函数名

  • QString转成char *
    • toUtf8()转为QByteArray;再使用data()转为char *

信号和连接信号

点击一个按钮触发自定义连接

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

    //创建一个老师对象
    this->zt = new Teacher(this);
    //创建一个学生对象
    this->stu = new Student(this);
    //连接带参数的信号和槽
    //指针 -> 地址
    //函数指针 -> 函数地址
    void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;//指向有参数的那个
    void(Student:: *studentSlot)(QString) = &Student::treat; //指向有参数的那个
    connect(zt,teacherSignal,stu,studentSlot);
    //重置窗口大小
    this->resize(600,400);
    QPushButton *btn = new QPushButton("下课",this);
    //connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);
	connect(btn,&QPushButton::clicked,zt,teacherSignal);

}

依旧是信号在调用槽函数

断开连接

//void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;//指向有参数的那个
//void(Student:: *studentSlot)(QString) = &Student::treat; //指向有参数的那个
//connect(zt,teacherSignal,stu,studentSlot);
disconnect(zt,teacherSignal,stu,studentSlot);//与连接参数一致

Qt4版本信号槽连接

connect(zt,SUGHAL(hungry),st,SLOT(treat()));

Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名函数对象。以简化编程工作

在这里插入图片描述
格式

[](){
    
    }();
  • 空,没有使用任何函数对象参数。
  • =,函数体内可以使用Lambda所在作用域范围内所有的局部变量(包括Lambda所在的this)并且是引用传递方式(相当于编译器自动为我们按引用传递了所有的局部变量)
  • &,函数体内可以使用lambda所在作用返回内所有可见局部变量(包括lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)
  • this,函数体内可以使用lambda所在类中的成员变量
  • a,将a按值进行传递,按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数时const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
  • &a,将a按引用进行传递。
  • a,&b:将a按值进行传递,b按引用进行传递
  • =,&a,&b出a和b按引用进行传递外,其他参数按照值进行传递
  • &,a,b出a和b按值传递外,其他参数都按引用进行传递。

猜你喜欢

转载自blog.csdn.net/yasinawolaopo/article/details/131073687