QT自定义信号与槽

4 篇文章 0 订阅

QT自定义信号与槽

概念:

所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。信号和槽是Qt特有的信息传输机制,是Qt设计程序的重要基础,它可以让互不干扰的对象建立一种联系。

槽的本质是类的成员函数,其参数可以是任意类型的。和普通C++成员函数几乎没有区别,它可以是虚函数;也可以被重载;可以是公有的、保护的、私有的、也可以被其他C++成员函数调用。唯一区别的是:槽可以与信号连接在一起,每当和槽连接的信号被发射的时候,就会调用这个槽。

槽能被用来接收信号者,除此之外它们也是普通的成员函数。槽不知道是否有信号与它连接起来,正如对象不知道它发出信号是否会被接收一样。这样的机制确保了可以使用Qt创建一个个完全独立的组件。你可以把你感兴趣的多个信号与一个个槽进行连接,也可以把一个信号与多个槽进行连接。甚至可以直接把一个信号连接到另一个信号(当第一个信号发送出去的时候,第二个信号紧接着被发送)。就这样,信号与插槽建立了强大的组件编程机制。

connect()函数最常用的一般形式:

connect(sender, signal, receiver, slot);

参数设置:

  • sender:发出信号的对象
  • signal:发出信号的对象发出的信号
  • receiver:接收信号的对象
  • slot:接收信号的对象在接收到信号之后所需要调用的函数

信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。如果不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少),但是不能说信号根本没有这个数据,你就要在槽函数中使用(就是槽函数的参数比信号的多,这是不允许的)。

在这里插入图片描述

自定义槽
  • 槽可以是任何成员函数、普通全局函数、静态函数
  • 槽函数和信号的参数和返回值要一致
  • 由于信号是没有返回值的, 槽函数也一定没有返回值
    首先在mainwidget.h中添加槽函数:
public slots:
    void ASlot();

之后在mainwidget.cpp文件中定义槽函数:

void MainWidget::ASlot()
{
    btn2->setText("^_^");
}

现在, 我们希望当Button2按下时, Button2显示的文本变成笑脸, 就需要将Button2的信号和我们自定义的槽函数连接:

connect(btn2, &QPushButton::clicked, this, &MainWidget::ASlot);

代码:

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QPushButton>
#include "subwidget.h"

class mainWidget : public QWidget
{
    Q_OBJECT

private:
    QPushButton btn1;
    QPushButton *btn2;

public slots:
    void Aslots();

public:
    mainWidget(QWidget *parent = 0);
    ~mainWidget();
};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    btn1.setParent(this);
    btn1.setText("Close");
    btn1.move(50,50);

    btn2 = new QPushButton(this);
    btn2->setText("btn_ok");
    btn2->move(150,50);

    connect(&btn1, &QPushButton::clicked, this, &MainWidget::close);

    connect(btn2, &QPushButton::clicked, this, &MainWidget::ASlot);

}

void MainWidget::ASlot()
{
    btn2->setText("^_^");
}

MainWidget::~MainWidget()
{

}

在这里插入图片描述

自定义信号

实现两个独立窗口之间的切换, 点击"Next" 跳到下一个窗口, 点击"Back" 返回到上一个窗口.

  • 信号没有返回值, 但可以有参数
  • 信号只有函数声明, 无需定义
  • 使用emit 发送信号
    首先修改当前窗口标题为"Window1", 并设置窗口大小:
    this->setWindowTitle("Window1");  // this->可以省略
    this->resize(300, 200);  // 长300, 宽200

之后修改Button2的文本"Button2"为"Next"
新建一个窗口
右键工程目录**“SignalAndSlot”** --> Add New:
img
选择 C++ --> C++ Class --> Choose:
img
输入Class name为SubWidget, Base class为QWidget, 点击Next, 点击Finish:
img
之后一个新的窗口类就新建好了:
img

修改新窗口的标题:
在subwidget.cpp中构造函数下, 设置窗口的标题为"Window2", 大小和Windows1一样:

    this->setWindowTitle("Windows2");
    this->resize(300, 200);

在新窗口中加入按键:
首先, 在subwidget.h中添加头文件, 然后声明按钮 b:

private:
    QPushButton b;

在subwidget.cpp中, 对按钮进行编辑:

    b.setParent(this);
    b.setText("Back");
    b.move(150, 50);

实例化SubWidget:
但是, 我们仅仅是写了一个新窗口的类, 还没有实例化, 所以我们在mainwidget.h中先包含subwidget的头文件, 然后实例化一个副窗口subWin对象:

    SubWidget subWin;

建立信号与槽的连接:
接下来, 我们来实现点击"Next"显示Windows2功能, 其实就是b2点击这个信号, 触发副窗口的show(), 并隐藏主窗口.
将mainwidget.h和mainwidget.cpp中所有的mySlot改为nextSlot. (共三处)
我们修改mainwidget.cpp中nextSlot()的定义:

void MainWidget::nextSlot()
{
    //  删除 b2->setText("^_^");
    subWin.show();
    this->hide();
}

connect(b2, &QPushButton::clicked, this, &MainWidget::nextSlot);不变. 保存并运行, 就可以实现切换到Window2窗口了. 但是还没有返回主窗口功能.
信号的创建和发送:
要实现Back功能, 就需要在"Back"按钮按下后, 副窗口发送一个信号, 然后主窗口收到这个信号后, 显示自己, 隐藏副窗口, 逻辑如下:
Back按下的信号 ----> 副窗口发送信号
副窗口的信号 ----> 主窗口show, 副窗口hide
下面看代码怎么写:
在subwidget.h中声明一个自定义的信号, 和用于发送该信号的槽函数:

signals:
    void backSignal();

public slots:
    void sendSignal();

由于信号只需声明, 无需定义, 所以只要在subwidget.cpp定义槽函数来发送信号:

void SubWidget::sendSignal()
{
    emit backSignal();
}

之后在Back按钮按下后, 通过这个槽函数发送返回信号:

connect(&b, &QPushButton::clicked, this, &SubWidget::sendSignal);

在mainwidget中需要再定义一个槽函数来处理back信号:
在mainwidget.h中声明槽函数

    void backSlot();

之后在mainwidget.cpp中定义:

void MainWidget::backSlot()
{
    this->show();
    subWin.hide();
}

之后connect信号与槽, 收到副窗口发送的信号后返回主窗口:

    connect(&subWin, &SubWidget::backSignal, this, &MainWidget::backSlot);

保存后运行, 现在可以在两个界面中切换了.
img
img

自己完成以下代码吧

完整代码:

链接: https://pan.baidu.com/s/1rtXU8e0oUy95mAok1zRDIA 密码: 7tc3
–来自百度网盘超级会员V5的分享

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGXWZUB7-1625824978383)(/home/zhou/.config/Typora/typora-user-images/image-20210709180200667.png)]

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT中的信号机制是QT框架核心的一个特性。它提供了一种在对象之间进行通信的简洁、高效的方式。自定义信号是在QT中扩展信号机制的一种方式,可以灵活地将自定义信号连接到相应的函数上。 在QT中,自定义信号的示例可以如下所示: ```cpp #include <QObject> #include <QPushButton> class MyButton : public QPushButton { Q_OBJECT public: MyButton(QWidget *parent = nullptr) : QPushButton(parent) {} signals: void clickedWithMessage(const QString& message); // 自定义信号 public slots: void onClicked() // 函数 { emit clickedWithMessage("Button is clicked!"); // 发射自定义信号,并传递消息 } }; class MyWidget : public QWidget { Q_OBJECT public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) { MyButton *button = new MyButton(this); connect(button, &MyButton::clickedWithMessage, this, &MyWidget::onButtonClicked); // 连接自定义信号函数 } public slots: void onButtonClicked(const QString& message) // 函数 { qDebug() << "Received message:" << message; } }; ``` 在这个示例中,我们自定义了一个派生自QPushButton的类MyButton,并在其中声明了一个自定义信号`clickedWithMessage`。当按钮被点击时,会发射该自定义信号,并传递一个消息。 然后,在MyWidget的构造函数中,我们创建了一个MyButton实例,通过`connect`函数将该按钮的自定义信号与MyWidget的函数`onButtonClicked`进行连接。 当按钮被点击时,MyWidget的函数`onButtonClicked`会被调用,接收到传递的消息并打印出来。 通过自定义信号,我们可以自由地在不同的对象之间实现消息的传递与处理,使得代码更加模块化和可维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值