自定义信号和槽
也就是connect()的第二个和第四个参数
-
signal没有返回值 void,可以有参数,可以重载
-
signal只需要声明,不需要实现
-
slot没有返回值 void,可以有参数,可以重载
-
早期的槽函数必须写到public slots:下,5.4版本之后可以写在public下,也可以写到全局下。不过为了兼容最好还是写在public slots下。
-
slot需要声明也需要实现
-
emit 发射信号
-
信号与槽函数参数类型必须需一一对应,信号的参数个数可以多于槽,但槽的参数个数不能多于信号。鼠标clicked只有一个bool参数,所以不能连接其它与之非对应参数类型的槽。
-
既可以将信号与槽相连,也可以将信号与信号相连
-
一个信号可以连接多个槽,多个信号可以连接一个槽
-
信号槽可以断开连接 disconnect
-
利用函数指针 明确指向函数重构的地址
void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry; -
QString 转成 char *:QString -> char * 先转成 QByteArray ( .toUtf8() ) 再转char*(.data())。例:foodName.toUtf8().data()
/*-----------自定义信号 begin--------------*/
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = 0);
signals:
void hungry(); //只需要做声明,不用做实现
void hungry(QString foodName); //重载
public slots:
};
#endif // TEACHER_H
/*----------触发函数,信号发射-------------*/
void Teacher::classIsOver()
{
//下课函数,调用后 触发老师饿了的信号
emit this->hungry();
}
void Teacher::classIsOver(QString foodName)
{
//下课函数,调用后 触发老师饿了的信号
emit this->hungry(foodName);
}
/*-----------自定义信号 over--------------*/
/*-----------自定义槽 begin--------------*/
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = 0);
signals:
public slots:
void treat(); //需要声明,也需要实现
void treat(QString foodName); //重载
};
#endif // STUDENT_H
/*--------------相应信号-----------------*/
void Student::treat()
{
qDebug()<< "请老师吃饭";
}
void Student::treat(QString foodName)
{
//QString -> char * 先转成 QByteArray ( .toUtf8() ) 再转char * ( .data() )
qDebug() << "请老师吃饭,老师要吃:" << foodName.toUtf8().data() ;
}
/*-----------自定义槽 over--------------*/
信号与槽连接与实现
#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;
};
#endif // WIDGET_H
/*-----------------------构造函数---------------------------*/
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);
//调用下课函数
this->zt->classIsOver();
/*----------------发生重构时声明函数指针连接---------------*/
//重构时构建函数指针指向重构函数
void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
void(Student:: *studentSlot)(QString) = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);
//调用下课
this->zt->classIsOver("宫爆鸡丁");
/*------------------使用按键连接信号----------------------*/
QPushButton * btn = new QPushButton("下课",this);
//因为有重构,所以要有定义函数指针
void(Teacher:: *teacherSignal_void)(void) = &Teacher::hungry;
void(Student:: *studentSlot_void)(void) = &Student::treat;
//按键连接信号
connect(btn,&QPushButton::clicked,zt,teacherSignal_void);
/*--------------------信号槽断开连接----------------------*/
disconnect(zt,teacherSignal,st,studentSlot);
}
QT4版本信号槽的连接
- Qt4版本 底层SIGNAL(“xxx”),SLOT( “xxx”)将其括号里的参数转化为字符串去匹配
- SIGNAL()与SLOT()既可以连接有参也可以连接无参,不用使用函数指针了
- 优点是写起来简单,很容易连接
- 缺点是编译器不会对你写进去的东西做检查,错误不易发现。比如参数类型,参数数量之类的都不会检查
- 高版本的QT兼容QT4的写法
connect( 信号,SIGNAL(),槽,SLOT() );