自定义信号要写在signal下,返回值是 void ,只需要声明,不需要实现,可以有参数,可以重载。槽函数早期版本必须写到public slots下,高级版本可以写到public或者全局下,返回值void,需要声明(treat),需要实现(cpp中),可以有参数,可以发生重载。在使用时需要连接信号与槽,并且给触发(emit)。
本次的需求是:下课后,我会发送一个信号 --> 饿了--> 我朋友接收信号--> 响应请我吃饭。本次需要两个类:My类 和 Friend类,分别对应我和我朋友。本次只进行有参的操作。过程:
① 首先添加两个类,属于QObject下,分别命名为 My 和 MyFriend。
② 在 widget.h 中进行 对象 和 下课信号 的声明
// 对象声明
My * my;
MyFriend * fri;
void classover();
③ 在 firend.h 中进行槽函数声明
public:
explicit MyFriend(QObject *parent = nullptr);
// 槽函数:早期版本必须写到public slots下 高级版本可以写到public或者全局下
// 返回值void,需要声明(treat),需要实现(cpp中)
// 可以有参数,可以发生重载
void treat(QString foodName);
④ 在 my.h 中进行信号的声明
signals:
// 自定义信号 写到signal下
// 返回值是 void ,只需要声明,不需要实现
// 可以有参数,可以重载
void hungry(QString foodName); // 说饿了并且说吃什么
⑤ 在 friend.cpp 中定义函数
void MyFriend::treat(QString foodName)
{
// 把QString转换成 char * 形式在输出的foodname就不会带""
// 先用(.toUtf8)转成QByteArray(字节数组型)再(.data())转char *
qDebug()<<"我朋友请我吃饭,我要吃:" << foodName.toUtf8().data();
}
⑥ 在 widget.cpp 中进行连接:
(1)创建 我 和 我朋友 的对象
// 创建一个我的对象
this->my = new My(this); // 指定好父类后,new之后就不需要管释放了
// 创建一个朋友的对象
this->fri = new MyFriennd(this);
(2)下课函数的创建
void Widget::classover()
{
// 下课后函数,调用后 触发我饿了的信号
// 触发的关键字 emit
emit my->hungry("肥牛鱼粉");
}
(3)连接 含参的 自定义信号和槽
// 连接含参的 信号和槽
// 指针可以指向地址,函数指针指向函数地址
void( My:: *mySingal )(QString) = &My::hungry;
void( MyFriend:: *friSlot )(QString) = &MyFriend::treat;
connect(my,mySingal,fri,friSlot);
(4)按钮的设置与连接
// 点击 下课按钮 触发下课
QPushButton * btn = new QPushButton("下课",this);
this->resize(600,400); // 重置窗口大小,resize是窗口this下的方法
// 点击按钮,触发下课
connect(btn,&QPushButton::clicked,this,&Widget::classover); // 信号连接槽
(5)测试
点击下课按钮,在应用程序栏中观察输出。
补充部分:
① 信号连接信号
connect(te,teacherSingal,st,studentSlot);
connect(btn,&QPushButton::clicked,my,mySingal);
// 先连接 friSlot 和 mySingal ,再连接 mySingal 和 &QPushButton::clicked
// ① 在触发QPushButton::clicked(点击按钮)时 ② 通过中介 mySingal ③ 触发 friSlot
② 断开连接
// 断开 friSlot 和 mySingal 之间的连接
disconnect(my,mySingal,fri,friSlot);
注意:①信号可以连接信号; ②信号可以连接多个槽函数; ③多个信号可以连接一个槽函数;
④信号和槽函数的参数类型必须一一匹配; ⑤信号参数个数 ≥ 槽函数参数个数。
③ lambda表达式:
用于定义并创建匿名的函数对象,基本格式如下:
connect(btn,&QPushButton::clicked,this,[x](){
});
1、[ x ]为表达式的开头且不能省略,x有如下取值:
(1)[=],为值传递方式,表示可以使用 所在作用范围内所有可见的局部变量,包括this,这是最常用的方式,下面的不常用;
(2)[=] 效果等同于 [&] ,其中 & 表示引用传递方式;
(3) [this] 函数体内可以使用lambda所在类的所有成员变量;
(4)[a] 将a按值进行传递,{}内只能传递a,不认其他变量,一般用于只修改其中的一个成员。[&b] 将b按引用进行传递;
(5)[=,&a,&b] 除a,b按引用传递,其他都按照值传递;
(6) [=,a,b] 除a,b按引值传递,其他都按照引用传递;
2、函数返回值:->返回值类型,前后数据类型要一致;
3、实现体{ } 里面内容为需要实现的部分,相当于槽函数里面放了一堆信号函数。