【Qt】信号和槽

一.定义

  • 信号与槽是对象之间的通信机制,是QT专有的机制

  • 声明了信号的对象,当其状态改变时,信号就由该对象发射出去,而且该对象只负责发送信号,它不知道另一端是谁在接收这个信号。

  • 槽用于接收和处理信号,一个槽并不知道是否有任何信号与自己相连接

信号

​​​​​​​信号的声明

  • 信号声明是在一个类的头文件中
  • signals关键字指出进入了信号声明区,随后即可声明自己的信号。
  • 例如,下面语句定义了一个信号:

​​​​​​​signals:     

          void stateChanged(int nNewVal);        

信号函数满足以下约束

  •  函数返回值是void类型
  • 开发人员只能声明、不能实现信号函数
  • 只有包含一个信号函数那个类及其派生类才能使用该信号函数
  • 信号函数的参数个数、类型由开发人员设定,这些参数的职责是封装类的状态信息,并将这些信息传递给槽函数
  • 只有QObject及其派生类才可声明信号函数

  • 槽函数和普通的C++成员函数一样,可以被正常调用
  • 唯一的特殊性就是很多信号可以与其相关联
  • 与其关联的信号被发射时,这个槽就会被调用
  • 槽函数可以 publicprotectedprivate

public slots:                

       void Function(int nNewVal)

       {

               //显示变量

               qDebug() << "new Values = " << nNewVal;

       }

关联信号与槽 

  • 通过调用QObject::connect()函数可以绑定一个信号函数和一个槽函数,函数常用格式:

​​​​​​​connect( sender, SIGNAL ( signal_func() ), receiver, SLOT( slot_func()) )

  • 其中senderreceiver 是指向对象的指针前者指向发射对象,后者指向处理对象 
  • signal_func以及slot_func分别是这两个对象中定义的信号函数和槽函数。

  • connect函数另一种形式:(霍亚飞 7.1.1信号和槽 P136)

​​​​​​​

​​​​​​​注意事项

  • 信号与槽机制如果使用不当的话,有可能产生死循环
  • 如果一个信号与多个槽相联系,当这个信号被发射时,相关的槽被激活的顺序将是随机的
  • 信号和槽的参数个数与类型必须一致。信息就是通过这些参数传递的

​​​​​​​

​​​​​​​二.举例

例一.无图形用户界面的简单信号/槽(从空项目开始)

1.exampleA.h

#include <QCoreApplication>

class CExampleA : public Qobject
{    
    Q_OBJECT

public:   

    CExampleA()  
    {       m_Value = 0;     }  

    void SetValue(int nNewVal)
    {    
            if(m_Value == nNewVal)   
                return;           

            m_Value = nNewVal;      
            emit stateChanged(m_Value);        
    }

signals:   
        void stateChanged(int nNewVal);        

private:   
        int m_Value;
}; 

2.exampleB.h

#include <QDebug>
#include <QCoreApplication>

class CExampleB : public QObject
{
   Q_OBJECT

public:   
   CExampleB()  {}

public slots:                            
   void Function(int nNewVal)   
   { 
        qDebug() << "new Values = " << nNewVal;   
   }
}; 

3.main.cpp

#include "exampleA.h"
#include "exampleB.h"

int main(){    
    CExampleA a;    
    CExampleB b;    
    Object::connect(&a, SIGNAL(stateChanged(int)), 
                               &b, SLOT(Function(int)));    
    a.SetValue(100);
    return 0;
}

结果:

 

 例二.使用控件内部定义好的信号/槽 (无UI的QDialog工程文件)

GUI窗口控件(例如按钮、标签、列表、编辑框等等)都预先定义好了若干信号,比如单击按钮就会发出clicked信号,还有诸如双击(doubleClicked)、进入(entered)、按下(pressed)等等信号都是预先在控件内部定义好的。

同时控件中也有一些预先定义好的槽,比如close()clear()等。

1.dialog.h

//在dialog.h文件头部添加:
#include <QLabel>	
#include <QPushButton>

//在dialog.h文件尾部添加声明:	
private:	
      QLabel  *label;	
      QPushButton *btn; 

2.dialog.cpp

//在dialog.cpp文件的构造函数添加代码,生成控件:	
    resize(300,300);    	
    label = new QLabel("label",this); 
   	btn = new QPushButton("Click Me",this);
    label->move(150,150); 
   	btn->move(125,110); 

//在dialog.cpp文件的构造函数添加代码如下:     

    connect(btn,SIGNAL(clicked()),label,SLOT(close()));

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值