Qt中信号槽的介绍及使用方法

这篇具有很好参考价值的文章主要介绍了Qt中信号槽的介绍及使用方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

三、信号槽

1. 信号槽的概念

2. 函数原型

2.1 自带信号 → 自带槽

2.2 自带信号 → 自定义槽

2.3 自定义信号

3. 参数传递

3.1 全局参数

3.2 信号槽传参

4. 对应关系

4.1 一对多

4.2 多对一


三、信号槽

1. 信号槽的概念

在之前的学习中,可以实现简单的UI效果,但是按钮不能点击。如果让按钮能在用户点击后执行某个代码,就需要用到Qt中的信号槽机制。

信号槽是Qt基于C++语法上新增的特性,可以实现对象之间的通信,形成一定因果关系。

使用信号槽的对象需要具备两个条件:

  • 通信的对象必须继承自QObject
  • 类中要有Q_OBJECT宏

2. 函数原型

QObject类是所有Qt对象的基类,此类中有一个静态成员函数connect,用于连接信号槽之间的因果关系,函数原型如下:

qt信号槽,qt,ui,开发语言

参数1:发射者,通信的对象,此对象是信号槽触发的来源,例如:按钮对象(n.)

参数2:信号函数,使用SIGNAL()包裹,表示发射者触发的效果,例如:点击(v.)

参数3:接收者,通信对象,此对象是执行结果代码的主体(n.)

参数4:槽函数,使用SLOT()包裹,表示接收者要执行的函数(v.)

为了方便讲解各种场景下使用信号槽的不同方式,分别使用三种类型进行讲解:

  • 自带信号 → 自带槽
  • 自带信号 → 自定义槽
  • 自定义信号 → 槽函数

2.1 自带信号 → 自带槽

这是最简单的一种连接方式,因为信号函数和槽函数都在Qt中预设了,只需要通过connect函数“连线”即可。

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

分析:

参数1,按钮对象;

参数2,点击函数;

参数3,窗口对象;

参数4:关闭函数。

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;
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

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

//    参数1,按钮对象 btn
//    参数2,点击函数 void	clicked()
//    参数3,窗口对象 this
//    参数4:关闭函数 bool	close()
    connect(btn,SIGNAL(clicked()),this,SLOT(close()));
}

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

2.2 自带信号 → 自定义槽

这种方式是使用频率最高的一种连接方式,因为Qt源代码中不可能囊括所有要执行的代码。实际上槽函数是一种特殊的成员函数,编写方式基本等同成员函数。

【例子】点击按钮,左下角移动窗口并输出移动后的窗口坐标。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QDebug>

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(300,300);
    btn = new QPushButton("移动并输出",this);
    btn->move(100,100);

    // 连接信号槽
    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}

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

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

2.3 自定义信号

自定义信号主要用于后期一些相对复杂的通信场景,本次学习强行使用,并不是功能实现的最优解。

信号函数是非常特殊的一种函数,只有声明,没有定义,且不能在代码中直接调用,可以配合emit关键字进行发射。

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

qt信号槽,qt,ui,开发语言

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;

    // 自定义槽函数
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(200,300);

    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
    connect(this,SIGNAL(mySignal()),this,SLOT(close()));
}

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

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

3. 参数传递

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

提示:

QPushButton显示文字的属性:

  • text : QString

getter:QString text() const

setter:void setText(const QString & text)

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:
    int count; // 记录点击的次数
    QPushButton* btn;

private slots:
    void btnClickedSlot(); // 按钮点击的槽函数
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    count = 0; // 属性赋予初始值

    resize(300,400);
    btn = new QPushButton("0",this);
    btn->move(100,250);

    connect(btn,SIGNAL(clicked()),
            this,SLOT(btnClickedSlot()));
}

void Dialog::btnClickedSlot()
{
    //    计数+1
    count++;
    // int → QString
    QString text = QString::number(count);
    // 设置显示
    btn->setText(text);
}

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

3.2 信号槽传参

使用信号槽也可以进行参数传递,但是这种方式通常用户后面较为复杂的情况,本次讲解的代码也不是最优解。

qt信号槽,qt,ui,开发语言

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;

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(300,300);
    btn = new QPushButton("0",this);
    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot1()));
    connect(this,SIGNAL(mySignal(int)),this,SLOT(mySlot2(int)));
}

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

void Dialog::mySlot1()
{
    // 静态局部变量
    static int count = 0;

    // 发射自定义信号
    emit mySignal(++count);
}

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

需要注意的是:

1. 理论上可以通过信号槽发送任意多个参数

2. 信号函数的参数个数必须大于等于槽函数的参数个数

3. 参数类型必须一致

4. 对应关系

4.1 一对多

同一个信号可以同时连接多个槽函数,也可以把这多个槽函数合并为一个槽函数。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QDebug>

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,600);
    btn1 = new QPushButton("一对多",this);
    btn1->move(100,200);
    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot1()));
    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));

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

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

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

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

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

4.2 多对一

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

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QDebug>

class Dialog : public QDialog
{
    Q_OBJECT

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

private:
    QPushButton *btn1;
    QPushButton *btn2;

private slots:
    void mySlot();
};

#endif // DIALOG_H

dialog.cpp文章来源地址https://www.toymoban.com/news/detail-703916.html

#include "dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(600,200);
    btn1 = new QPushButton("1",this);
    btn1->move(200,100);
    btn2 = new QPushButton("2",this);
    btn2->move(400,100);

    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot()));
    connect(btn2,SIGNAL(clicked()),this,SLOT(mySlot()));
}

void Dialog::mySlot()
{
    qDebug() << "自定义槽函数";
}

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

到了这里,关于Qt中信号槽的介绍及使用方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Qt】信号槽的三种连接方式

    实现观察者模式,可以使用函数回调,但注册回调函数有一定局限,安全性也没有保证。所以一定程度上可以说 Qt 信号槽是对回调机制进行了封装。 Qt 的信号槽能够连接(connect) 和编译通过,需要满足两个条件 信号的参数个数大于等于槽函数 信号槽的参数个数相同的部分,

    2024年02月13日
    浏览(44)
  • QT信号与槽的第五个参数

    1、Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。 2、Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,

    2024年02月13日
    浏览(50)
  • QT的信号槽的四种写法和五种链接方式

    目录 四种信号槽写法: 五种连接方式: 实例: 常见错误及改正: 错误1: 未连接信号与槽 错误2: 信号和槽参数不匹配 错误3: 未使用Q_OBJECT宏 错误4: 跨线程连接未处理   在Qt中,信号(Signal)和槽(Slot)是一种用于对象之间通信的机制,用于实现一种松耦合的方式。信号被

    2024年02月13日
    浏览(41)
  • QT中EventFilter使用方法

    Qt处理事件共有五种方式,其中第三种方式:” 在QObject中注册事件过滤器 ”的基本使用方法如下:如果对象使用installEventFilter()函数注册了事件过滤器, 目标对象中的所有事件将首先发给这个监视对象的eventFilter()函数 。eventFilter()函数 返回true ,则取消事件( 事件不再向目标

    2024年02月03日
    浏览(29)
  • 手机两个卡槽的正确使用方法,您用对了吗?

    手机上有两个卡槽,该如何搭配才能使话费降到最低?你又是怎么搭配的? 这篇文章小编就来告诉你,如何在不换号的情况下,将自己的话费降到最低。 首先卡槽一我们就用8元保号套餐。 卡槽二,我们就可以办理一张网上的大流量卡,小编办理的就是电信小龙卡29元155G,

    2024年02月13日
    浏览(33)
  • Qt qDebug基本的使用方法详解

    DebugView下载   qDebug是Qt框架中用于输出调试信息的一个宏。它类似于C++标准库中的std::cout,用于在控制台中输出调试信息。qDebug的使用非常简单,可以用于输出各种类型的数据,例如字符串、整数、浮点数等。 qInfo、qWarning、qCritical等,用于输出不同级别的调试信息。   

    2024年04月22日
    浏览(50)
  • Qt | 配置文件QSetting的使用方法

    1、简介 配置文件常见的作用是启动软件是保留上次软件退出是的界面状态,如果不保留配置,且软件界面的内容又比较多,重启软件后界面恢复默认,那么每次打开界面都需要重新设置,这样比较麻烦,所以可以使用配置文件进行保存,软件启动的时候自动加载。 2、QSett

    2024年02月13日
    浏览(35)
  • Qt QThread的moveToThread方法使用

    从 Qt4.4 版本之后,因为 QThread 的 run 方法创建新线程这样实现与 Qt 设计的理念不符,Qt 主推使用 moveToThread 方法来创建新线程。 QThread应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject的子类中,然后将

    2024年02月14日
    浏览(36)
  • Qt Creator使用Clang Format方法

    习惯性的想格式化代码,发现Qt Creator默认居然是没有代码格式化的,只有一个缩进。 Qt Creater中有个插件:beautifier,在\\\"帮助-关于\\\"插件中,开启“Beautifier”即可(会提醒需要重启Qt creator)。 注:Qt Creator安装包中不包含这个格式化工具,它的作用是调用格式化工具进行格式

    2024年02月10日
    浏览(41)
  • QT中使用QtXlsx库的三种方法 QT基础入门【Excel的操作】

    对于Linux用户,如果Qt是通过“ apt-get”之类的软件包管理器工具安装的,请确保已安装Qt5开发软件包qtbase5-private-dev QtXlsx是一个可以读写Excel文件的库。它不需要Microsoft Excel,可以在Qt5支持的任何平台上使用。该库可用于从头开始生成新的.xlsx文件从现有.xlsx文件中提取数据编

    2024年02月12日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包