[QT开发 05_信号和槽机制]

知识点1:信号与槽机制的介绍

所谓信号槽,实际就是观察者模式。当 某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信 号(signal)这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己 的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出 时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的 事件,某一个操作就会被自动触发。

理解:观察者模式

知识点2:connect函数+系统自带的信号和槽

connect(sender, signal, receiver, slot);

参数:

1、信号发出者

2、信号

3、信号接受者

4、接受到信号执行任务(槽函数)

在Qt中,"widget" 是一个通用术语,指的是可视化用户界面的基本构建块。Widget 是用户界面元素的抽象概念,可以包括按钮、文本框、滑块、复选框等等。在Qt框架中,QWidget 是所有用户界面元素的基类,几乎所有的用户界面元素都是从 QWidget 派生而来的。

在Qt中,使用 QWidget 可以创建一个窗口或者一个面板,并在其上放置各种不同类型的子部件(widgets)。这些子部件可以是按钮、标签、文本框等等,它们都是 QWidget 的子类。

信号:

信号:void  clicked(bool checked = false);
 

槽函数():void close();

举例:点击窗口按钮,关闭窗口

    //创建按钮
    QPushButton * button = new QPushButton("点击关闭窗口",this);//创建按钮
    this->resize(600,400);//设置窗口大小
    button->resize(100,100);//设置按钮的大小

    //信号与槽
    connect(button,&QPushButton::clicked,this,&Widget::close);

知识点3:自定义信号与槽

步骤1:确定场景

老师饿了,学生请客

小哥敲门,家人开门

步骤2:添加老师和学生类

步骤3:在老师类中声明信号+在学生类中声明并实现槽函数

teacher.h(信号:一般在signals里面写,返回值void,参数可以存在,仅声明不需要实现,可以重载)

signals:
    void hungury();

student.h(槽函数:一般在public slots里面写,对于一些高版本的qt来说,也可以写到public或者全局;返回值void,参数可以存在,需要声明并实现,可以重载)

public slots:
    void treat();

student.cpp(在student.h中声明,在student.cpp中定义)

#include<QDebug>    //这里需要加上头文件


void Student::treat()
{
    qDeBug()<<"请老师吃饭";
}

步骤4:创建对象

this->tea=new Teacher(this);
this->stu=new Student(this);
connect(tea,&Teacher::hungury,stu,&Student::treat);

步骤5:触发信号(下课)

widget.h(声明触发信号的成员函数

widget.cpp(定义触发信号的成员函数+调用该成员函数)

补充:

点击按钮,请吃饭

方式一:

 connect(button,&QPushButton::clicked,this,&Widget::ClassOver);

方式二:信号连接信号

知识点4:重载自定义信号与槽

步骤1:重新写信号声明(代参数)

void hungury(QString food)

步骤2:重新写槽函数声明及定义(带参数)

void treat(QString food)
void Student::treat(QString food)
{
    qDebug()<<"请老师吃饭"<<food;
}

步骤3:由于函数重载了,所以需要利用函数指针指向函数地址,然后再做连接

void(Teacher::*teachersignal)(QString)=&Teacher::hungury;
void(Student ::*studentslot)(QString)=&Student::treat;
connect(tea,teachersignal,stu,studentslot);

注意:去掉打印的双引号和中间空格的方法

补充:Qt4版本信号槽写法(了解)

connect(tea,SIGNAL(hungury(QString)),stu,SLOT(treat(QString)));

使用注意:

1、Qt5在语法上是完全兼容4的,反之不可以。

2、如果是Qt4版本的信号与槽写法,一定要注意信号和槽的名称不要写错。

知识点5:信号与槽总结

自定义信号槽注意事项:

1、发送者与接受者需要时QObject的子类(槽函数全局,lambda除外)

2、信号和槽函数返回值都是void

3、信号需要声明不需要定义实现,槽函数需要声明也需要定义实现()。

4、槽函数是普通的成员函数,作为成员函数会受到public,private,protected的影响;

5、使用emit在恰当的位置发送信号;

6、使用connect()函数连接信号和槽。

7、任何成员函数,static函数,全局函数和Lambda表达式都可以作为槽函数。

8、信号槽要求信号和槽的参数一致所谓一致,是参数类型一致

        如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来,这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

        举例:

        signal(QString)   和   slot(QString)      √

        signal(QString,QString)  和  slot(QString)      √

        signal(QString )  和  slot(QString,QString)      ×

        signal(QString,QString,int)   和   slot(QString,int)  √

 拓展:

1、信号与槽对应可以一对一,一对多(发出信号,槽函数一个一个执行,顺序不确定),多对一(任意信号发出,槽函数都会执行)

2、信号可以连接信号

3、槽可以被断开连接(disconnect),槽也可以被取消连接(当一个对象delete了,取消这个对象上的槽)

4、使用C++11中的lambda表达式。

知识点6:Lambda表达式

概念:C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。

语法:

[capture](parameters) mutable ->return-type { statement }
1、[ ]是引出符,capture捕获列表,捕获的是那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量

2、( parameters)参数列表,与普通函数的参数列表一致的。

3、mutable可修改标示符,按值传递函数对象参数时(默认仅读权限),加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。

4  ->return-type  返回值类型

5、{ statement }函数体,内容跟普通函数一致。

1、[ ]标识一个Lambda的开始,这部分必须存在,不能省略。

空             没有使用任何函数对象参数。

=              函数体内可以使用Lambda所在作用范围内所有可见的局部变量。值传递。

&              函数体内可以使用Lambda所在作用范围内所有可见的局部变量。引用传递

a              将a按值进行传递。

&a             将a按引用进行传递。

this           函数体内可以使用Lambda所在类中的成员变量。

a, &b        将a按值进行传递,b按引用进行传递。

2、( )参数列表,如果不需要传递参数的话,()可以一同省略。

3、如果使用mutable,参数列表()不能省略的即使参数为空;如果使用mutable,修改拷贝,而不是值本身。

4、->return-type 返回值类型,如果不需要,->return-type都可省略。

5、{函数体},可以使用参数列表,也可以使用捕获列表。

使用:

1、通过lambda表达式输出内容

    [](){
        qDebug()<<"lambda is runing";
    }();


=========================================
    auto fun=[](){
        qDebug()<<"lambda is runing";
    };
    fun();
    
    

2、测试参数列表和可修改标示符(如果无mutable,m=300报错)

int m=10;
auto  fun=[m](int a,int b)mutable{
    qDebug()<<"lamda is running!";
    m=300;
    return a+b;
};

int sum=fun(100,200);
qDebug()<<sum;

3、槽函数一般可用lambda表达式

        QPushButton * myBtn = new QPushButton ("点击",this);
        this->resize(600,400);

        connect(myBtn,&QPushButton::clicked,this,[=] ()mutable {
           qDebug() << "按钮被按下";
        }
        );

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值