Qt的信号与槽的使用

1、信号和槽机制

信号与槽用于两个对象之间,当一个部件发生改变时,希望其他部件也能了解到该变化,也希望任何对象与其他对象进行通信。

  • Qt封装了具体操作系统的消息机制,遵循经典的GUI消息驱动事件模型。 消息驱动机制

  • QT定义了与操作系统消息相关的自己的概念,即信号与槽。

  • 信号signal是由操作系统产生的消息。

  • 槽slot是程序中的消息处理函数。

  • connect将系统消息绑定到消息处理函数。

  • 信号到槽的连接必须发生在两个QT对象间。

bool QObject::connect ( 
    const QObject * sender, //发生对象
    const char * signal, //消息名
    const QObject * receiver, //接收对象
    const char *method, //接收对象的成员函数
    Qt::ConnectionType type = Qt::AutoConnection )

eg:

connect(ui->btn, &QPushButton::clicked, this, &MainWindow::change_state);
connect(ui->btn, SIGNAL(clicked()), this, SLOT(change_state()));//qt4

信号和槽机制的特色和优越性:

  • 信号和槽机制是类型安全的,相关联的信号和槽的参数必须匹配;

  • 信号和槽是松耦合的,信号发送者不知道也不需要知道接受者的信息;

  • 信号和槽可以使用任意类型的任意数量的参数。

    虽然信号和槽机制提供了高度的灵活性,但就其性能而言,还是慢于回调机制的。回调函数 性能差异在应用程序中还是很难体现出来的

2 、QT中的相关的关键字

  • SIGNAL用于指定消息名
  • SLOT用于指定消息处理函数名
  • Q_OBJECT所以自定义槽的类必须在类声明的开始处加上Q_OBJECT
  • slots用于在类中声明消息处理函数
  • signals用于在哪种声明信号

3、 使用信号和槽应该注意

  • 需要继承自QObject或其子类;
  • 在类声明的最开始处添加Q_OBJECT宏;
  • 槽中的参数的类型要和信号的参数的类型相对应,且不能比信号的参数多;
  • 信号只用声明,没有定义,且返回值为void类型。
  • 声明一个信号要使用signals关键字,在signals前面不能使用public、private和protected等限定符因为只有定义该信号的类及其子类才可以发射该信号。
  • 一个信号可以关联到多个槽上,多个信号也可以关联到同一个槽上,如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,但是它们执行的顺序是随机的,无法指定它们的执行顺序。
  • 槽是普通的成员函数,也有访问权限。
    • 槽的访问权限决定了谁能够与其相关联。同普通的C++成员函数一样,槽函数也分为三种类型,即public slots、private slots和protected slots
    • public slots:使用publicslots声明的槽表示任何对象都可将信号与之相连接。在组件编程中,可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确的传递。
    • protected slots:使用protected slots声明的槽表示当前类及其子类可以将信号与之相连接。适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。
    • private slots:使用private slots声明的槽表示只有类自己可以将信号与之相连接,适用于联系非常紧密的类。
  • 槽函数就是一个普通函数,在没有与信号一起使用的时候,可以以普通成员函数的方式来使用

4 、信号与槽三种使用方式:

1、转到槽(快捷方式)

​ 鼠标右键点击发送信号的控件,选择转到槽,选择对应的信号,会在.cpp中生成槽函数,在槽函数内部编写要执行的代码(行为)。

2、自定义槽函数和连接函数

​ 在接收信号的类里面声明槽函数,槽函数的定义跟类的普通成员函数定义方式一样。

​ 在发送信号和接收信号的对象建立之后代码中使用connet函数进行信号与槽函数的连接

3、自定义信号、槽函数和连接函数

​ 在发送信号的类中自定义一个信号,在声明信号的类或派生类发送.

​ 在接收信号的类里面声明槽函数,槽函数的定义跟类的普通成员函数定义方式一样。

​ 在发送信号和接收信号的对象建立之后代码中使用connet函数进行信号与槽函数的连接

自动生成的槽函数命名规范:on_对象名称_对象信号(),在后两种方式中如果槽函数按照这样的命名方式,就可以不写连接。

5、信号与槽使用小结

1、信号声明位置,信号发送位置?

信号声明在发送信号的类中声明(.h)中

①自定义一个信号

signals:://信号不能像普通函数一样使用,也不需要权限声明
	void mysignal();//信号不需要定义

②发送信号

emit mysignal();

2、槽函数声明位置,槽函数定义位置?

接收信号的类中声明槽函数(.h)

private slots://槽函数在类中的声明
    void myslot();//槽函数的定义跟类的普通成员函数定义方式一样
//槽函数定义
void MainWindow::myslot()
{
    ui->label_2->setText("完成设置");
}

匿名函数方式

qt5支持 c++11中的lambda表达式

connect(btn,&QpushBtton::clicked,[=](/*参数*/){
    //函数体
});

3、connect建立信号和槽函数的链接?

在同时能够看到信号发送者和信号接收者的地方

//绑定信号和槽函数
//    connect(this, SIGNAL(mysignal()), this, SLOT(myslot()));
    connect(this, &MainWindow::mysignal, this, &MainWindow::myslot);

6、信号与槽传递数据

通过参数来传递

void send_data(QString msg); void recv_data(QString msg);

注意:

(1)信号不带参数,槽函数一定不能带参数

(2)信号带参数,槽函数可以不带参数,如果槽函数带参数,得保证类型和信号的参数类型一致

(3)信号参数个数可以是多个,槽函数可以没有,也可以有多个(顺序要与信号的参数一致),也可以有其中的某个

7、断开连接

当信号与槽没必要进行保持关联时,可以使用disconnect函数来断开连接

bool QObject::disconnect ( 
    const QObject * sender, 
    const char * signal, 
    const QObject * receiver, 
    const char *method ) 

disconnect函数断开发送者中的信号与接收者中的槽函数之间的关联。

在disconnect函数中0可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者sender不能为0,其它三个参数的值可以等于0。

①断开与某个对象关联的任何对象

disconnect(sender,0,0,0);
//sender->disconnect();

②断开与某个特定信号的任何关联

disconnect(sender,SIGNAL(mySignal()),0,0);
//sender->disconnect(SIGNAL(mySignal()));

③断开两个对象之间的关联

dixsconnect(sender,0,recevier,0);
//sender->disconnect(recevier);
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yengi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值