Qt从入门到放弃之:自定义信号和槽

知识点

信号和槽的概念

信号和槽机制是QT自行定义的一种通信机制,实现对象之间的数据交互,当某个对象状态发生改变时将会发送信号,该函数可以被其他对象接收,接收后会执行一个指定的操作(槽)

信号和槽的定义

class QXX:public QObject{
	Q_OBJECT	//元对象编译器(moc)
signals:
	void mySignal(...);//信号
访问控制限定符 slots:
	void mySlot(...){...}//槽
};
注意:
	1>使用信号和槽机制必须是QObject的直接子类或间接子类
	2>信号函数只需要声明,不能定义
	3>槽可以被某个信号触发执行,也可以像普通成员函数一样直接调用
信号
  • 信号声明时使用signals:关键字

  • 信号的返回值是void

  • 信号可以有参数,也可以发生重载

  • 信号只需要声明,不需要定义
    在这里插入图片描述

  • 信号的触发使用emit关键字
    在这里插入图片描述

  • 槽需要声明也需要定义,可以带参数,可以重载
  • 槽函数在早期要写在public slots:下,5.6以及高版本可以直接写在public:里,或者是全局函数(建议还是写在public slots:中,代码可读性高,后期维护方便)
  • 槽函数可以作为普通函数调用

信号和槽的连接

  • connect函数原型
[static] QMetaObject::Connection QObject::connect(
	const QObject *sender, 
	const QMetaMethod &signal, 
	const QObject *receiver, 
	const QMetaMethod &method, 
	Qt::ConnectionType type = Qt::AutoConnection);
参数:
	sender: 信号的发送对象(QObject任何子类对象)
	signal: 信号函数()
		注:SIGNAL(信号函数(参数))//将信号函数转换为const char*
	receiver: 要执行槽函数的接收对象(OBject任何子类对象)
	method: 槽函数
		注:SLOT(槽函数(参数))//将槽函数转换为const char*
  • 调用格式
connect(信号发送的对象,SIGNAL(信号函数(参数)),信号接收对象,SLOT(槽函数(参数)));

信号和槽的连接注意事项

  • 信号函数的参数和槽函数的参数要保持一致
QObject::connect(A,SIGNAL(sigfunc(int)),B,SLOT(slotfunc(int)));//ok
//QObject::connect(A,SIGNAL(sigfunc(void)),B,SLOT(slotfunc(int)));//error
  • 槽函数可以带有缺省参数
class B:public QObject{
public slots:
	void slotfunc(int = 0){}
};
QObject::connect(A,SIGNAL(sigfunc(void)),B,SLOT(slotfunc(void)));
  • 信号函数的参数可以多于槽函数的参数,多于的参数将会被槽函数忽略
QObject::connect(A,SIGNAL(sigfunc(int)),B,SLOT(slotfunc(void)));//ok
  • 一个信号可以同时连接多个槽函数
QObject::connect(A,SIGNAL(sigfunc(int)),B1,SLOT(slotfunc1(int)));//ok
QObject::connect(A,SIGNAL(sigfunc(int)),B2,SLOT(slotfunc2(int)));//ok
//注:当A信号被发送时,连接的B1,B2两个槽函数都将会被执行
  • 多个信号连接到同一个槽函数上
QObject::connect(A1,SIGNAL(sigfunc1(int)),B,SLOT(slotfunc(int)));//ok
QObject::connect(A2,SIGNAL(sigfunc2(int)),B,SLOT(slotfunc(int)));//ok
//注:不论多个信号中的哪一个发送了信号,都会触发槽函数
  • 两个信号可以直接连接作用相当于触发一个信号后另一个信号也被触发
QObject::connect(A1,SIGNAL(sigfunc1(int)),A2,SIGNAL(sigfunc2(int)));//ok
//注:当一个信号被发送后所连接的另外的信号也将会被发送

信号的触发

  • 信号的触发使用emit关键字
    在这里插入图片描述

  • 信号的触发要在信号和槽函数连接之后才会有效果
    -

demo运行效果

程序运行时将在widget类的构造函数中调用老师类中的信号触发函数,从而触发信号的发送,再由学生类中的绑定的相应的槽函数来打印相关信息
在这里插入图片描述

文件结构

在这里插入图片描述

代码

signalAndSlot.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    student.cpp \
    teacher.cpp \
    widget.cpp

HEADERS += \
    student.h \
    teacher.h \
    widget.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

头文件

widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "teacher.h"
#include "student.h"

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
};
#endif // WIDGET_H
teacher.h
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class teacher : public QObject
{
    Q_OBJECT
public:
    explicit teacher(QObject *parent = nullptr);
    void classover();

signals:
    void hungry();
};

#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 feast();
};

#endif // STUDENT_H

.cpp文件

main.cpp
#include "widget.h"

#include <QApplication>

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

widget.cpp
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
   teacher* t = new teacher;
   student* s = new student;
   connect(t,&teacher::hungry,s,&student::feast);
   t->classover();
}

Widget::~Widget()
{
}


teacher.cpp
#include "teacher.h"

teacher::teacher(QObject *parent) : QObject(parent)
{

}

void teacher::classover()
{
    emit hungry();

}

student.cpp
#include "widget.h"

#include <QApplication>

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值