Qt的自定义信号与槽

        自定义信号要写在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、实现体{ } 里面内容为需要实现的部分,相当于槽函数里面放了一堆信号函数。

猜你喜欢

转载自blog.csdn.net/weixin_58351753/article/details/127460453