首页 > 其他分享 >Qt信号与槽

Qt信号与槽

时间:2024-04-08 09:33:57浏览次数:25  
标签:函数 pushButton ui 信号 MainWindow Qt

我们在使用Qt的时候,不使用Qt Designer 的方式进行开发,使用ui文件,信号与槽的连接方式是生成代码之后才能在setupUi函数里才能看到,或者需要进入Ui设计器里的信号槽模式里才能看到信号槽的连接。所以我们最好使用代码绘制界面。

一.Qt信号与槽机制

信号(Signal)就是在特定情况下被发射的事件,槽(Slot)就是对信号响应的函数。槽函数与一般函数不一样的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

信号与槽关联是用QObject::connect() 函数实现的,其基本格式是:

QObject::connect(sender,SIGNAL(signal()),recevier,SLOT(slot));

connect()是QObject类的一个静态函数而QObject是所有Qt类的基类,在实际调用时可以忽略前面的限定符,所以可以直接写为:

connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

其中,sender 是发射信号的对象的名称,signal() 是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。receiver 是接收信号的对象名称,slot() 是槽函数 的名称,需要带括号,有参数时还需要指明参数。

当信号和槽函数带有参数时,在 connect()函数里,要写明参数的类型,但可以不写参数名称。

一个信号可以连接另外一个信号(说明了 connect 万物皆可连,非常好用!),例如:

connect(pushButton,SIGNAL(objectNameChanged(QString)),this, SIGNAL(windowTitelChanged(QString)));

这样,当一个信号发射时,也会发射另外一个信号,实现某些特殊的功能。

严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。 如果不匹配,会出现编译错误或运行错误。

在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT(特别重要)。

当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。 只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。

总结如下图,可以看到发送者与发送的信号是在一起的,接收者与接收的信号/槽是在一起 的。它们不能在 connect()方法里写乱顺序!由发送者发送出信号到接收者用信号/槽接收。

信号槽连接的方法已经讲解过了,接下来讲解一下断开连接的方法,使用disconnect()。

bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)

信号与槽机制是 Qt GUI 编程的基础,使用信号与槽机制可以比较容易地将信号与响应代码关联起来。

二. 如何在项目里创建信号

信号只需声明,无需定义。所以我们只需要在 mianwindow.h 里声明信号即可。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/*引入 QPushButton */
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

signals:
    /* 声明一个信号,只需声明,无需定义 */
    void pushButtonTextChanged();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

三. 如何在项目中创建槽

创建槽的方法也很简单,也是直接在 mianwindow.h 里直接声明槽,在 mianwindow.cpp 里 实现槽的定义,声明槽必须写槽的定义(定义指函数体的实现),否则编译器编译时将会报错。

槽有以下特点:

  1. 槽可以是任何成员函数,普通全局函数,静态函数

  2. 槽函数和信号的参数和返回值要一致

根据上面的槽特点,由于我们声明了信号 void pushButtonTextChanged(); 所以我们声明的槽函数必须是无返回值类型 void,和无需参数。所以声明槽的代码如下。此外 我们还声明一个 QPushButton 对象 pushButton。对象 pushButton 可以写成简写 btn。这个根据个 人习惯即可!简写的名称建议不要让人看不懂即可!同时还声明一个按钮点击的槽。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
/*引入 QPushButton */
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

signals:
    /* 声明一个信号,只需声明,无需定义 */
    void pushButtonTextChanged();

public slots:   
    /*声明一个槽函数*/
    void changeButtonText();
    /*声明按钮点击的槽函数*/
    void pushButtonClicked();
private:
    /* 声明一个对象 pushButton 也可以是btn,易于读懂就行 */
    QPushButton *pushButton;
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

在 mainwindow.cpp 里实现 声 明 的 槽 函 数 void changeButtonText(); 和 void pushButtonClicked();。同时还实例化了 pushButton 对象。代码如下。

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow) //new一个UI中的MainWindow,这里是一种初始化成员的方法
{
    //ui->setupUi(this);//这句话是进行界面初始化,将this作为参数传到setupUi里,ui界面
    //文件的对象会以this为父对象,所有子对象将显示在MainWindow里,我们要想使用ui里的对象
    //必须将代码写在ui->setUi(this)这句话之后,因为ui->setupUi(this)会先初始化里面的对象,只有初始化
    //里面的对象我们才能使用这个对象

    /* 设置窗体的宽为 800,高为 480 */
    this->resize(800,480);
    /* 实例化 pushButton 对象 */
    pushButton = new QPushButton(this);
    /* 调用 setText()方法设定按钮的文本 */
    pushButton->setText("我是一个按钮");
}

MainWindow::~MainWindow()
{
    delete ui;
}
/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{
    /* 使用 emit 发送信号 */
    emit pushButtonTextChanged();
}
/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{
    /* 在槽函数里改变按钮的文本 */
   pushButton->setText("被点击了!"); 
}

四. 如何在项目中连接信号与槽

信号槽连接的代码如下

connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked()));
connect(this,SIGNAL(pushButtonTextChanged()), this, SLOT(changeButtonText()));

注意,发送信号的对象,和接收的信号的对象。因为我们 pushButtonClicked()是本类里定 义的槽,所以用 this 来接收。同理pushButtonTextChanged()也是本类定义的信号。所以发送 者写成 this。changeButtonText()也是本类的槽函数,所以接收槽的对象也是 this。

在 mainwindow.cpp 中信号槽连接的代码如下

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow) //new一个UI中的MainWindow,这里是一种初始化成员的方法
{
    //ui->setupUi(this);//这句话是进行界面初始化,将this作为参数传到setupUi里,ui界面
    //文件的对象会以this为父对象,所有子对象将显示在MainWindow里,我们要想使用ui里的对象
    //必须将代码写在ui->setUi(this)这句话之后,因为ui->setupUi(this)会先初始化里面的对象,只有初始化
    //里面的对象我们才能使用这个对象

    /* 设置窗体的宽为 800,高为 480 */
    this->resize(800,480);
    /* 实例化 pushButton 对象 */
    pushButton = new QPushButton(this);
    /* 调用 setText()方法设定按钮的文本 */
    pushButton->setText("我是一个按钮");
    /* 信号与槽连接 */
    connect(pushButton, SIGNAL(clicked()), this,SLOT(pushButtonClicked()));
    connect(this, SIGNAL(pushButtonTextChanged()), this,SLOT(changeButtonText()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
/* 实现按钮点击槽函数 */
void MainWindow::pushButtonClicked()
{
    /* 使用 emit 发送信号 */
    emit pushButtonTextChanged();
}
/* 实现按钮文本改变的槽函数 */
void MainWindow::changeButtonText()
{
    /* 在槽函数里改变按钮的文本 */
  pushButton->setText("被点击了!");
}

五. 学会使用 Qt 类的信号与槽

Qt里有大量的信号与槽,都是Qt自定义好的,那么我们该如何使用Qt信号与槽呢?

进入 QPushButton 的定义处,我们看到 QPushButton 不止 clicked 信号,还有其他信号,也 有 QPushButton 的槽函数(返回上一步按 Alt + 方向左键)。在这里我们只是简单的看了如何在 已知信号和槽里查找其他信号与槽。实际上在开发中我们经常需要使用 Qt 帮助文档来查看 Qt 定义的信号与槽。我们将在下一章里讲解 Qt 帮助文档的使用,帮助文档里面就有如何查看 Qt 的信号与槽等等。

标签:函数,pushButton,ui,信号,MainWindow,Qt
From: https://blog.csdn.net/m0_66746512/article/details/137474144

相关文章

  • VS+QT编程找不到新增UI文件控件对象的问题
    转载自:VS写Qt项目时,ui界面拖拽的控件代码找不到引用的解决办法_vsqt中ui下的组件没有-CSDN博客1.保存Ui文件在拖拽控件之后,Ctrl+S2.重新编译ui文件鼠标右键选择要编译的UI文件,找到编译 3.右键项目,重新扫描解决方案 ......
  • 基于计算机视觉的交通信号违章检测系统(闯红灯违章检测)
    Introduce:该系统可以实时检测交通信号灯违规:城市中越来越多的汽车会导致大量交通拥堵,这意味着如今在孟加拉国和世界各地,交通违规行为变得更加严重。这造成了严重的财产破坏和更多可能危及人民生命的事故。为了解决令人震惊的问题并防止这种深不可测的后果,需要交通违章检测......
  • Qt 中信号槽的连接方式总结
    Qt中信号槽的连接方式,即:QObject::connect()函数的第五个参数Qt::ConnectionType,共有五种连接方式。它决定了是否立刻将特定的信号传递给槽函数,还是将其放在队列中,稍后进行传递。1.Qt::AutoConnection:自动连接(默认方式)当第五个参数缺省时默认为该连接方式。具体为:当接收者......
  • SpringBoot集成mqtt启动就不断报已断开连接问题
    踩坑记录,实在是天坑!!!原因一:clientId相同,即clientId重复导致(不过我不是这个问题)我的问题是:项目启动成功后,控制台不停地反复输出:已断开连接,,,加了重连机制后,则不停地输出:重连失败,已连接客户机,,,尼玛,,关键点还在于我能接收到订阅的消息(不影响消息处理),这又是什么情况,明明没断连,确一直......
  • 2003年重邮801信号与系统考研真题与详解
    文章目录前言一对一极速提分辅导2003年重邮801信号与系统考研真题与详解前言重庆邮电大学801信号与系统考研真题与详解系列已制作完毕,现将逐步以免费的方式更新在微信公众号、博客上,其特点如下:①质量高:所有文字、公式、图形均自己编写、制作,确保清晰、质量高、掌握......
  • MQTT 错误码 说明
    //成功#defineMQTTCLIENT_SUCCESS0 //失败,通用#defineMQTTCLIENT_FAILURE-1 //客户端未连接,未连接,先使用引起#defineMQTTCLIENT_DISCONNECTED-3 //已达到允许同时处理的最大消息数(#defineMAX_MSG_ID65535)#defineMQTTCLIENT_MAX_MESSAGES_INFLIGHT-4 //UTF-8字......
  • VS+QT 创建UI界面自动生成.h和cpp文件
    1.创建QT窗口界面创建内容:qtwidgetClass:创建.UI文件以及对应的窗口类文件,其余的只创建ui文件,记一笔免得又忘记了自己填写类名称,选择基类,完成创建就好 ......
  • qt Qml qml Property的使用方法
    9.property简介:自己声明一个变量名,自己赋值,外部可以对其赋值可以声明一个属性变量intstringvardouble等等也可以声明一个控件用于外部写入到本qmlrectanglecomponent等等其他:在property前面可以加readonly就可以只能外部访问,不能修改在property前面可以加req......
  • qt Qml qml MouseArea的属性和信号方法
    Mousearea属性:​acceptedButtons:​接受的鼠标按键,默认是左键Qt.LeftButton|Qt.RightButton|Qt.AllButtons等等​pressedButtons:​按下的是什么键?左键or右键等Rectangle{color:"yellow"anchors.centerIn:parentwidth:200hei......
  • 毕业设计程序开源 Spring Boot+vue.js+Echart+mysql +QT+halcon
    1.介绍 涉及到的技术框架比较多,但是也不难,相关技术需要些基础。目前还是个半成品,还有些数据图表和QT功能没做完善,本来想在前端部分做大数据分析平台的,后续有空再完善。下面简单介绍一下。源代码此处:链接:https://pan.baidu.com/s/1904kLOv4EDJkcBuuNe1jqw?pwd=6666 提取码:6......