(3)Qt——信号槽

目录

1.信号槽的概念**

2.信号槽的连接***

2.1自带信号 → 自带槽

2.2 自带信号 → 自定义槽

2.3 自定义信号

3. 参数传递**

3.1 全局变量

3.2 信号槽传参

4. 对应关系**

4.1 一对多

4.2 多对一


1.信号槽的概念**

信号槽指的是信号函数与槽函数的连接,可以使用不同的对象通过信号槽连接在一起,从而实现对象之间的通信。

可以把信号槽的连接认为是对象之间的一种约定:如果.......,则.......

信号槽是Qt新增的特性,C++是不支持的,使用信号槽的前提条件:

1)通信的对象的类中要有Q_OBJECT

2)通信的对象必须继承自(包括间接继承)自QObject 【所以Qt对象的基类】类

2.信号槽的连接***

信号槽是一种约定,主要通过以下实现

// 参数1:信号发射者 是一个名词,因果关系中的因,表示发射信号函数的对象
// 参数2:信号函数的名称 是一个动词,需要使用SINGNAL()包裹,因果关系的因,表示动作
// 参数3:信号接收者 是一个名称,因果关系中的果,表示执行动作(操作函数)的对象
// 参数4:槽函数的名称 是一个动词,需要使用SLOT()包裹,因果关系中的果,表示动作
QObject::connect(const QObject * sender, 
				    const char * signal, 
				    const QObject * receiver, 
				    const char * method) [static]

依次通过三种方式讲解信号槽的连接

1)自带信号自带槽

2)自带信号自定义槽

3)自定义信号自带/自定义槽

2.1自带信号 → 自带槽

这是最简单的一种信号槽连接方式,因为信号函数和槽函数都在Qt源代码中实现了,只需要查询文档找到名称手动连接即可。

【例子】点击按钮,关闭窗口

分析:

参数1:按钮对象

参数2:点击信号

参数3:窗口对象

参数4:关闭槽

 

 

 

 

 

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(400,400);
    btn = new QPushButton("关",this);
    btn->move(200,200);
    // 连接信号槽
    // 参数1:按钮对象
    //	参数2:点击信号 clicked
    //	参数3:窗口对象
    //	参数4:关闭槽 close
    connect(btn,SIGNAL(clicked()),this,SLOT(close()));
}

Dialog::~Dialog()
{
    delete btn;
}

2.2 自带信号 → 自定义槽

当槽函数完成的功能比较复杂时,Qt的源代码无法完全覆盖这样的功能,此时需要程序员手动写一个槽函数,并实现和连接。

需要注意的是槽函数实际上是一种特殊的成员函数。

【例子】点击按钮,把窗口向右下角移动,并输出当前的窗口坐标。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;

    // 声明自定义槽函数
private slots:
    void mySlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(400,400);
    btn = new QPushButton("关",this);
    btn->move(200,200);
    // 连接信号槽
    //   参数1:按钮对象
    //	参数2:点击信号 clicked
    //	参数3:this
    //	参数4:自定义槽函数mySlot
    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}

// 定义槽函数
void Dialog::mySlot()
{
    // 先获得当前窗口的坐标
    int x = this->x();
    int y = this->y();
    // 移动窗口
    move(x+10,y+10);
    // 输出当前坐标值
    qDebug() << this->x() << this->y();
}

Dialog::~Dialog()
{
    delete btn;
}

2.3 自定义信号

自定义信号主要用户后期一些特殊的情况,目前还没发举例,因此基于下面的案例,强行使用,并不是问题的最优解。

需要注意的是,信号函数没有权限,只有声明没有定义。不能调用信号函数,只能发射信号函数。

【例子】点击按钮,关闭窗口。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;

    // 自定义槽函数
private slots:
    void mySlot();

    // 声明自定义信号
signals:
    void mySignal();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(500,500);
    btn = new QPushButton("关闭",this);
    btn->move(250,250);

    // 连接第一个信号槽
    connect(btn,SIGNAL(clicked()),
            this,SLOT(mySlot()));
    // 连接第二个槽函数
    connect(this,SIGNAL(mySignal()),
            this,SLOT(close()));
}

// 定义槽函数
void Dialog::mySlot()
{
    // 发射自定义信号函数
    emit mySignal();
}

Dialog::~Dialog()
{
    delete btn;
}

3. 参数传递**

3.1 全局变量

可以借助一个全局(根据实际应用的范围来指定)可访问的变量来实现。

【例子】点击按钮,按钮上显示点击的次数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton *btn;
    // 计数变量
    int count;

    // 自定义槽函数
private slots:
    void mySlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    count = 0; // 赋予初始值
    resize(400,400);
    btn = new QPushButton("0",this);
    //btn->move(200,200);
    btn->setGeometry(150,150,50,50);
    // 连接信号槽
    connect(btn,SIGNAL(clicked()),
            this,SLOT(mySlot()));
}

void Dialog::mySlot()
{
    // 计数+1
    count++;
    // int → QString
    // QString QString::number(int n) [static]
    QString text = QString::number(count);
    // 设置按钮的新文字
    btn->setText(text);
}

Dialog::~Dialog()
{
    delete btn;
}

运行结果:

3.2 信号槽传参

本节强行使用信号槽传参,此方法主要用于后续复杂问题的解决。

【例子】点击按钮,按钮上显示点击的次数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton* btn;
    int count = 0; // 计数

private slots:
    void mySlot1(); // 自定义槽函数1
    void mySlot2(int); // 自定义槽函数2

signals:
    // 自定义信号槽,带参数!!!
    void mySignal(int);
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(400,400);
    btn = new QPushButton("0",this);
    btn->move(200,200);

    // 第一个信号槽连接
    connect(btn,SIGNAL(clicked()),
            this,SLOT(mySlot1()));
    // 第二个信号槽的连接
    connect(this,SIGNAL(mySignal(int)),
            this,SLOT(mySlot2(int)));
}

void Dialog::mySlot1()
{
    // 增加计数
    count++;
    // 发射自定义信号
    emit mySignal(count);
}

void Dialog::mySlot2(int count)
{
    // int → QString
    QString text = QString::number(count);
    // 更新显示
    btn->setText(text);
}

Dialog::~Dialog()
{
    delete btn;
}

需要注意的是:

  • 理论上可以通过信号槽传递任意多个参数。
  • 信号的参数个数必须大于等于槽的参数个数。
  • 参数类型必须匹配。

4. 对应关系**

4.1 一对多

同一个信号可以连接多个槽函数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QPushButton *btn1;
    QPushButton *btn2;

private slots:
    void mySlot1();
    void mySlot2();
    void mySlot3();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(300,400);
    btn1 = new QPushButton("一对多",this);
    btn1->move(100,200);
    // 一对多
    connect(btn1,SIGNAL(clicked()), this,SLOT(mySlot1()));
    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));
    //disconnect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));

    btn2 = new QPushButton("一对多",this);
    btn2->move(100,250);
    connect(btn2,SIGNAL(clicked()),this,SLOT(mySlot3()));
}

void Dialog::mySlot1()
{
    qDebug() << "A";
}

void Dialog::mySlot2()
{
    qDebug() << "B";
}

void Dialog::mySlot3()
{
    // 槽函数也是成员函数,直接调用mySlot1和2
    mySlot1();
    mySlot2();
}

Dialog::~Dialog()
{
    delete btn1;
    delete btn2;
}

4.2 多对一

多个信号也可以连接同一个槽函数,代码略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值