Qt的信号和槽机制

一、系统自带的信号和槽

1.connect函数

        connect函数是建立信号发送者、信号、信号接收者、槽四者关系的函数。

        connect(sender, signal, receiver, slot);

        参数解释:

                sender:信号发送者

                signal:信号

                receiver:信号接收者

                slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

         注意:1.默认情况下,他们死者没有关系,通过connect建立四者的关系。

                    2.信号和槽,本质都是函数。

                    3.connect里面的四个参数都是指针:

                                connect(btn,&QPushButton::clicked,this,&Widget::hide); 

                    4.使用connect的时候保留&符号:1.可以提高代码可读性

                                                                          2.自动提示   

QPushButton *btn = new QPushButton("按钮1",this);
    //关闭 this->close()

    //    按钮
    //    被点击
    //    窗口
    //    关闭
    connect(btn,&QPushButton::clicked,this,&widget::close);

二、自定义信号和槽

1.自定义信号:

        1.函数声明在类头文件的signals域下面

        2.void类型的函数,没有返回值

        3.可以有参数,也可以重载

        4.只有声明,没有实现定义

        5.触发信号 emit obj->sign(参数...)

2.自定义槽

        1.函数声明在类头文件的public/private/protected slots域下面(qt4以前的版本)

        2.qt5 就可以声明在类的任何位置,还可以是静态成员函数、全局函数、lambda表达式

        3.void 类型的函数,没有返回值

        4.可以有参数,也可以重载

        5.不仅有声明,还得有实现

3.带参数的自定义信号和槽

        声明函数的时候就带上参数就行,例如老师说他饿了,说要吃黄焖鸡,学生就请吃黄焖鸡

        调用带参数的信号函数 emit pTeacher->hungry("黄焖鸡");

4.参数二义性问题

        1.使用函数指针赋值,让编译器自动挑选符合类型的函数

        2.使用static_cast 强制转换 ,让编译器自动挑选符合类型的函数

5.实用场景

        场景:下课了,老师说他饿了,学生就请吃饭

        信号发送者:老师

        信号:老师饿了

        信号接收者:学生

        槽:请吃饭

        创建多少个类:Teacher,Student

        信号:hungry 1个 Teacher

        槽:treat 1个 Student

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{    

    //老师和学生的两个对象创建
    pTeacher = new Teacher(this);
    pStudent = new Student(this);
    //建立连接
    //    connect(pTeacher,&Teacher::hungry,pStudent,&Student::treat);


    //老师说要吃黄焖鸡,学生就请吃黄焖鸡
    //hungry多加一个参数,QString
    //treat 也要一个参数,QString
    //因为函数发生了重载,所以解决
    /*
     * 1 使用函数指针赋值,让编译器挑选符合类型的函数
     * 2 使用static_cast 强制转换,也是让编译器自动挑选符合类型的函数
     */

    //    void (Teacher::*teacher_qString)(QString) = &Teacher::hungry;
    //    void (Student::*student_qString)(QString) = &Student::treat;

    //    connect(pTeacher,teacher_qString,pStudent,student_qString);




    //使用static_cast 来转换无参的函数

    connect(pTeacher,
            static_cast<void (Teacher::*)()>(&Teacher::hungry),
            pStudent,
            static_cast<void (Student::*)()>(&Student::treat));



    //下课了
    this->classIsOver();
}

void Widget::classIsOver()
{
    //出发老师饿了的信号
    emit pTeacher->hungry();
    //带参数的信号发射
    emit pTeacher->hungry("黄焖鸡\r\n");
}

三、信号和槽的拓展

1.一个信号可以连接多个槽

一个信号建立了多个connect,那么当信号发射的时候,槽函数的调用顺序是随机的

2.一个槽可以连接多个信号

3.信号可以连接信号

connect(第一个信号发送者,第一个信号,第二个信号发送者,第二个信号)

    信号可以连接信号
        QPushButton *btn = new QPushButton("按钮1",this);
        connect(btn,&QPushButton::clicked,
                pTeacher,
                static_cast<void (Teacher::*)()>(&Teacher::hungry));

4.信号可以断开连接:disconnect

connect参数怎么填,disconnect就怎么填

//信号可以断开连接
disconnect(pTeacher,teacher_qString,pStudent,student_qString);

5.信号和槽的参数关系

1.信号和槽函数的参数类型必须对应

2.信号和槽函数的参数个数不需要一致,信号函数参数个数>=槽函数参数个数

hungry(QString)    ->       treat()         //ok
hungry(QString)    ->       treat(int)     	//编译出错
hungry(QString,int)->       treat(int)     	//编译出错

注意:必须同时满足以上两点。 

四、Qt4版本的信号槽写法

1.使用规则

        1.使用两个宏SIGNAL、SLOT

        2.connect使用不一样,信号和槽函数声明差不多

        3. connect(信号发送者,SIGNAL(函数原型) ,信号接收者,SLOT(函数原型))

2.好处与坏处

        好处:没有重载二义性的问题

        坏处:写错了,编译期间不会报错

3.SIGNAL和SLOT宏的原理

        就是将后边的参数转成字符串      类似 #define toStr(arg)  #arg     -> "arg"、

        推荐:使用Qt5以后的

五、QDebug

1.概念

        QDeubg输出QString默认会转义

2.解决方法

        1.将QString转成 char *

qDebug()<<"Student treat teacher with "<<what.toUtf8().data();

        2. 使用qDebug().noquote()

qDebug().noquote()<<"Student treat teacher with "<<what;

六、Lambda表达式

1.格式

[capture](parameters) opt ->retType
	{
	……;
	}

2.含义

       1. [capture] 捕获外部局部变量的列表,值传递,直接填变量名 ,引用传递就使用&变量名

                使用= 值传递捕获所有局部变量

                使用& 应用传递捕获所有局部变量

                有特殊的捕获方式的变量在后边另外指定

        2.如果是值传递捕获进来的变量默认是const , 需要修改的话要使用 mutable选项

        3.返回值类型可以省略,编译器自动计算返回值

        4.以后都推荐使用 [=](){} 的形式

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt信号机制是其最重要的特性之一,它提供了一种灵活而高效的通信方式。信号可以在不同对象之间进行通信,使得这些对象能够相互响应和交互。 信号Qt中定义的一种特殊的函数,用于表示某个事件的发生。一个类可以定义一个或多个信号信号可以在特定的情况下被触发,比如用户点击了一个按钮或者其他的操作发生了一些特定的事件。信号的声明通常位于类的头文件中。 是一个特殊的成员函数,用于接收信号并对其进行响应。一个类可以定义一个或多个函数,用于处理不同的信号函数可以有任意的参数和返回值,但是需要与信号的参数列表和返回值类型匹配。函数的声明通常位于类的头文件或者源文件中。 信号通过Qt的元对象系统来进行连接。当信号被触发时,与之相关联的函数会被调用。信号之间的连接可以通过Qt提供的connect函数来实现,也可以在Qt Creator中通过可视化界面来进行连接。 信号之间的连接是动态的,可以在运行时进行创建、修改和断开。这种机制使得对象之间的通信变得非常灵活,能够很好地支持Qt的事件驱动编程模型。 总结起来,Qt信号机制是一种通过信号函数来实现对象间通信的灵活机制信号用于表示事件的发生,函数用于对信号进行响应。通过Qt的元对象系统,可以在运行时动态地连接、修改和断开信号之间的关联。这种机制使得对象之间的通信变得简单而高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值