介绍

  • 只有Qt类才能定义信号,且该类必须在头文件中声明
  • 信号函数只能通过signals关键字进行声明,不能定义,且返回值必须是void类型
  • 信号函数的属性会被自动设置为protected类型
  • 发送信号时,只需要通过emit关键字调用信号函数即可
  • 如果信号函数的参数多于槽函数时,多于的参数将被忽略
  • 槽函数的返回值必须是void类型,且可以被其它普通成员函数调用

自定义信号示例:

class MySignal : public QObject
{
  Q_OBJECT
signals:     //自定义信号函数
  void SendSignal(int i);

public:
  void send(int i)
  {
    emit SendSignal(i); //调用信号函数,发送信号
  }
};

PS 信号如果要设为public,设置如下所示:

class MySignal : public QObject
{
  Q_OBJECT
public:
signals:     //自定义信号函数
  void SendSignal(int i);

public:
  void send(int i)
  {
    emit SendSignal(i); //调用信号函数,发送信号
  }
};

自定义槽函数示例:

class MySlot : public QObject
{
  Q_OBJECTprotected slots:
  void RecvSlot(int i)
  {
    qDebug()<<"Send:"<<sender()->objectName(); //打印发送对象名
    qDebug()<<"Recv:"<<i;
    qDebug()<<endl;
  }
};

信号与槽的组合

  • 信号函数可以连接多个槽函数
  • 多个信号函数可以连接一个槽函数
  • 一个信号就可以连接到另一个信号
  • 通过connect函数进行连接,也可以通过disconnect函数取消连接

示例1-多个信号连接一个槽:

MySignal s1;
    MySignal s2;
    MySlot t;

    s1.setObjectName("Signal1");
    s2.setObjectName("Signal2");     QObject::connect(&s1,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));
    QObject::connect(&s2,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));

    s1.send(10);
    s2.send(12);

打印:

Send: "Signal1" 
Recv: 10

Send: "Signal2"
Recv: 12

示例2-信号1连接信号2,信号2连接槽:

MySignal s1;
    MySignal s2;
    MySlot t;
    s1.setObjectName("Signal1");
    s2.setObjectName("Signal2");
    QObject::connect(&s1,SIGNAL(SendSignal(int)),&s2,SIGNAL(SendSignal(int)));
    QObject::connect(&s2,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));
    s1.send(10);
    s2.send(12);

打印:

Send: "Signal2" 
    Recv: 10

    Send: "Signal2"
    Recv: 12