QTday2(信号与槽机制——很重要!!!)

news2025/1/13 13:08:29

一、Xmind整理:

二、上课笔记整理:

1.信号与槽

class Widget : public QWidget
{
    Q_OBJECT        //信号与槽的元对象

signals:
    void my_signal();          //自定义信号函数

public slots:
    void my_slot();            //自定义的槽函数

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

private:
    Ui::Widget *ui;
};

2.qt4版本的连接函数,该版本的连接是不友好的连接

[static] QMetaObject::Connection           //返回值是一个连接,并且该函数是一个静态成员函数
    QObject::connect(                      //函数名
        const QObject *sender,             //信号的发射者,是组件的指针
        const char *signal,                //要发射的信号是一个C语言风格的字符串,将信号函数传递进来时,需要使用SIGNAL宏进行转换
        const QObject *receiver,           //信号的接受者,是组件的指针
        onst char *method)                 //处理信号的槽函数,是C风格字符串,将槽函数传递进来时,需要使用SLOT宏进行转换
注意:信号函数必须是信号的发射者所在的类中有的信号函数,而槽函数也必须是信号的接受者中有的槽函数
举个例子:
  QLabel *label = new QLabel;
  QScrollBar *scrollBar = new QScrollBar;
  QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
                   label,  SLOT(setNum(int)));

3.qt5版本的连接函数

[static] QMetaObject::Connection           //返回值是一个连接,并且该函数是一个静态成员函数
    QObject::connect(                   //函数名
        const QObject *sender,              //信号的发射者,是组件的指针
        PointerToMemberFunction signal,     //信号函数的函数指针变量,直接填写函数名即可
        const QObject *receiver,           //信号的接受者,是组件的指针
        PointerToMemberFunction method)    //槽函数的函数指针变量,直接填写函数名即可
        
举个例子:
  QLabel *label = new QLabel;
  QLineEdit *lineEdit = new QLineEdit;
  QObject::connect(lineEdit, &QLineEdit::textChanged,
                   label,  &QLabel::setText);

4.信号连接外部函数或lambda表达式

[static] QMetaObject::Connection                //返回值是一个连接,并且该函数是一个静态成员函数
    QObject::connect(                 //函数名
        const QObject *sender,            //信号的发射者,是组件的指针
        PointerToMemberFunction signal,      //信号函数的函数指针变量,直接填写函数名即可
        Functor functor)                 //处理信号的功能函数,可以是全局函数,也可以是lambda表达式

举个例子:
  void someFunction();
  QPushButton *button = new QPushButton;
  QObject::connect(button, &QPushButton::clicked, someFunction);

Lambda 表达式作为槽函数:

  QByteArray page = ...;
  QTcpSocket *socket = new QTcpSocket;
  socket->connectToHost("qt-project.org", 80);
  QObject::connect(socket, &QTcpSocket::connected, [=] () {
          socket->write("GET " + page + "\r\n");
      });

5.断开信号与槽的连接

//断开按钮对应的槽函数
void Widget::on_btn6_clicked()
{
    disconnect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));

    disconnect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);

}

6.信号与槽的案例

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QDebug>
#include<QPushButton>
#include<QTextToSpeech>          //文本转语音的头文件

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT        //信号与槽的元对象

signals:
    void my_signal();          //自定义信号函数

public slots:
    void my_slot();            //自定义的槽函数

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

private slots:
    void on_btn2_clicked();

    void on_btn6_clicked();

private:
    Ui::Widget *ui;

    //自定义一个按钮
    QPushButton *btn3;

    //定义一个播报员指针
    QTextToSpeech *speecher;

};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

void fun()
{
    qDebug()<<"我是过路的";
}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //给播报员实例化空间
    speecher = new QTextToSpeech(this);

    //给btn3实例化空间
    this->btn3 = new QPushButton("按钮3", this);
    this->btn3->move(ui->btn2->x(), ui->btn2->y()+50);
    this->btn3->resize(ui->btn2->size());

    //使用qt4版本的连接,将按钮3发射的pressed信号与按钮1的槽函数进行连接
    connect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));
    //参数1:信号的发射者,按钮3的指针
    //参数2:要发射的信号,是在按钮所在类中拥有的信号函数,需要使用SIGNAL宏函数进行转换
    //参数3:信号的接受者,ui界面上的按钮1指针
    //参数4:处理信号的槽函数,是信号接收者所在类中拥有的槽函数
    //注意:该链接方式是不友好的链接,原因是 即使宏函数中写错,编译器不报错,但是没有现象

    //使用qt5版本的链接,将ui界面上的btn4按钮发射的clicked信号,与当前界面的自定义的槽函数连接
    connect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);

    //将ui界面上的按钮5,发射的clicked信号,连接到全局函数中
    connect(ui->btn5, &QPushButton::clicked, fun);

    //将ui界面上的按钮5发射的clicked信号连接到lambda表达式中
    connect(ui->btn5, &QPushButton::clicked, [&](){
    //        qDebug()<<"我是路人乙";
        speecher->say("我是路人乙");
    });
    //将当前界面的my_signal信号连接到自定义的槽函数中
    connect(this, &Widget::my_signal, [&](){
        speecher->say("已经成功断开按钮3和按钮4的连接");
    });
}

Widget::~Widget()
{
    delete ui;
}

//自定义槽函数的实现
void Widget::my_slot()
{
    static  int num = 0;
    if(num%2)
    {
        ui->btn2->setEnabled(false);
    }else
    {
        ui->btn2->setEnabled(true);
    }
    num++;
}

//该函数就是按钮2的clicked信号对应的槽函数
void Widget::on_btn2_clicked()
{
    static int num = 0;


    if(num % 3 == 0)
    {
        ui->btn2->setStyleSheet("background-color:red;");
    }else if(num % 3 == 1)
    {
        ui->btn2->setStyleSheet("background-color:yellow;");
    }else
    {
        ui->btn2->setStyleSheet("background-color:green;");
    }


    num++;
}


//断开按钮对应的槽函数
void Widget::on_btn6_clicked()
{
    disconnect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));

    disconnect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);

    //发射自定义的信号
    emit my_signal();
}

7.信号函数与槽函数参数个数总结

1、信号函数和槽函数进行链接时,一般要求信号函数和槽函数的参数保持一致
connect(信号发送者, SIGNAL(signalFun()),信号接收者, SLOT(slotFun()));     //Ok
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int)));     //Ok
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(int, char)));     /connect(信号发送者, SIGNAL(signalFun(char, int)),信号接收者, SLOT(slotFun(int, char)));     //False
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(char)));     //False
2、当信号函数的参数大于槽函数的参数时
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun()));     //Ok
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(int)));     //Ok
connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(char)));     //False
3、当信号函数的参数小于槽函数的参数时
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int, char)));     //False
connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int, char=0)));     //Ok
#include <QWidget>
#include<QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE


class Widget : public QWidget
{
    Q_OBJECT

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

signals:
    void my_signal();                //自定义信号函数
    void my_signal_1(QString msg);      //自定义带参数的信号函数

public slots:
    void btn1_slot1();       //声明函数
    void btn1_slot2();       //声明函数
    void my_signal_1_slot(QString m = "lallalallalaal");

private slots:
    void on_btn3_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //1、一个信号可以连接多个槽函数,当信号发射时,所有与之连接的槽函数全部都执行
    connect(ui->btn1, &QPushButton::clicked, this, &Widget::btn1_slot1);
    connect(ui->btn1, &QPushButton::clicked, this, &Widget::btn1_slot2);

    //2、一个槽函数可以连接多个信号
    connect(ui->btn2, &QPushButton::clicked, this, &Widget::btn1_slot1);

    //3、信号函数连接信号函数,表明发射第一个信号后,第二个信号跟着发射
    connect(ui->btn2, &QPushButton::clicked, this, &Widget::my_signal);
    connect(this, &Widget::my_signal, [](){
        qDebug()<<"德玛西亚";
    });

    //4、连接my_signal_1信号到自定义的槽函数中
    connect(this, SIGNAL(my_signal()), this, SLOT(my_signal_1_slot()));

}

Widget::~Widget()
{
    delete ui;
}

//槽函数1的定义
void Widget::btn1_slot1()
{
    qDebug()<<"Good good study";
}
//槽函数2的定义
void Widget::btn1_slot2()
{
    qDebug()<<"day day up";
}

//按钮3发射的信号对应的槽函数
void Widget::on_btn3_clicked()
{
    qDebug()<<"我现在想发射一个my_signal_1信号";

    //emit my_signal_1("hello world");
    emit my_signal();
}
//定义处理my_signal_1的槽函数
void Widget::my_signal_1_slot(QString m)
{
    qDebug()<<"我是处理my_signal_1信号的槽函数:"<<m;
}

8.使用信号与槽完成两个界面的跳转

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

signals:
    void jump();          //自定义跳转函数

private slots:
    void on_jumpBtn_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

/***********************************第二个界面的头文件*******************/
#ifndef SECOND_H
#define SECOND_H

#include <QWidget>

namespace Ui {
class Second;
}

class Second : public QWidget
{
    Q_OBJECT

public:
    explicit Second(QWidget *parent = nullptr);
    ~Second();

public slots:
    void jump_slot();    //定义有关处理跳转信号的槽函数

private:
    Ui::Second *ui;
};

#endif // SECOND_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //信号函数也可以连接信号函数
    //connect(ui->jumpBtn, &QPushButton::clicked, this, &Widget::jump);
}

Widget::~Widget()
{
    delete ui;
}

跳转按钮对应的槽 函数
void Widget::on_jumpBtn_clicked()
{
    //发射跳转信号
    emit jump();

    //关闭当前 界面
    this->hide();
}

/*************************************第二个文件的源文件****************/
#include "second.h"
#include "ui_second.h"

Second::Second(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Second)
{
    ui->setupUi(this);
}

Second::~Second()
{
    delete ui;
}

//处理跳转信号函数对应的槽函数
void Second::jump_slot()
{
    this->show();          //将当前界面进行展示
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/955542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

码云使用记录

码云使用记录 主要步骤 1、https://gitee.com 注册 2、下载Git 3、配置SSH 4、创建远程仓库 5、切到本地项目目录下将本地项目推到远程 前两步根据提示进行即可&#xff0c;下面从第三步开始讲解 3、配置SSH&#xff08;用于提交代码和更新代码&#xff09; https://gitee.…

IDEA全局统一设置Maven

原来每次打开新建的项目都需要经过 File-> Settings 重新配置maven&#xff0c;这样很不爽 然而经过 File-> New Projects Setup -> Settings for New Projects 后&#xff0c;再如上图配置后就全局设置好了

文件包含漏洞利用的几种方法

文章目录 安装环境启动环境漏洞花式利用蚁剑连接图片马读取敏感文件&#xff08;hosts&#xff09;读取该网站的php源码 代码审计 安装环境 安装phpstudy&#xff0c;下载MetInfo 5.0.4版本软件&#xff0c;复制到phpstudy目录下的www目录中。 打开phpstudy&#xff0c;访问浏…

Ubuntu系统下配置 Qt Creator 输入中文、配置软件源的服务器地址、修改Ubuntu系统时间

上篇介绍了Ubuntu系统下搭建QtCreator开发环境。我们可以发现安装好的QtCreator不能输入中文&#xff0c;也没有中文输入法供选择&#xff0c;这里需要进行设置。 文章目录 1. 配置软件源的服务器地址2. 先配置Ubuntu系统语言&#xff0c;设置为中文3. 安装Fcitx插件&#xff…

Android 下第一个fragment app 先Java 后Kotlin

看着视频学习的&#xff0c;Fragment&#xff1a;3.Fragment使用方法_哔哩哔哩_bilibili 在android studio 下新建一个工程&#xff0c;类型是 Empty View Activity&#xff0c;本身就有一个Activity。就有文件MainActivity.java 或者kt&#xff0c;还有一个layout 文件&#…

如何给小程序会员添加档案记录

​给小程序会员添加档案记录&#xff0c;可以帮助商家更好地管理会员信息和提供个性化的服务。下面就具体介绍怎么设置档案记录。 1. 找到指定的会员卡。在管理员后台->会员管理处&#xff0c;找到需要添加档案记录的会员卡。也支持对会员卡按卡号、手机号和等级进行搜索。…

unity 之 如何获取父物体与子物体

文章目录 获取父物体获取子物体 获取父物体 在Unity中&#xff0c;你可以使用Transform组件的属性来获取对象的父物体。以下是在C#脚本中如何获取父物体的示例代码&#xff1a; using UnityEngine;public class GetParentExample : MonoBehaviour {void Start(){// 获取当前物…

人生中的孤独

孤独是一种深刻而痛苦的情感状态&#xff0c;在这个喧嚣而充满人群的世界中&#xff0c;许多人都曾经或正在经历孤独的阶段。 孤独并不仅仅是身边缺乏他人的陪伴&#xff0c;更是一种内心的空虚和失落。 孤独的人生可能来源于各种原因。 有些人可能因为缺乏亲密的人际关系&…

基于STM32的空气质量检测LCD1602显示报警仿真设计(仿真+程序+讲解)

本设计 基于STM32的空气质量检测报警仿真设计(仿真程序讲解&#xff09; 1.主要功能2.仿真3. 程序4. 资料清单&下载链接 基于STM32的空气质量检测报警仿真设计(仿真程序讲解&#xff09; 仿真图proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设…

信息安全——密钥管理

根据近代密码学观点&#xff0c;密钥体制的安全应当只取决于密钥的安全&#xff0c;而不取决于对密码算法的保密。因此密钥管理是至关重要的。 从技术上讲&#xff0c;密钥管理包括密钥的产生、存储、分配、组织、使用、更换和销毁等一系列技术问题。每个密钥都有其生命周期&a…

医学影像软件 Sante DICOM Viewer Crack

医学影像软件 Sante DICOM Viewer Crack Sante DICOM Viewer是用于恢复&#xff0c;查看&#xff0c;存储&#xff0c;存档&#xff0c;管理和刻录医学图像的最佳软件之一。它是专业的DICOM显示器&#xff0c;转换器&#xff0c;PACS客户端&#xff0c;迷你PACS服务器&#xff…

【0831作业】QTday2 加载资源文件、信号与槽机制(非常重要)、界面跳转

一、思维导图 二、今日面试题 三、今日知识回顾 1 信号与槽的连接 .h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QDebug> #include<QPushButton> #include<QTextToSpeech>//文本转语音类 QT_BEGIN_NAMESPACE namespace Ui { c…

比较opencv,pillow,matplotlib,skimage读取图像的速度比较

上面这些库都被广泛用于图像处理和计算机视觉任务&#xff1b; 不同的图像读取库&#xff08;OpenCV&#xff0c;Pillow&#xff0c;matplotlib和skimage&#xff09;的读取速度&#xff0c;是怎么样的一个情况&#xff1f; 下面分别从读取速度&#xff0c;以及转换到RGB通道…

端到端自动驾驶综述

End-to-end Autonomous Driving: Challenges and Frontiers 文章脉路 Introduction 从经典的模块化的方法到端到端方法的一个对比, 讲了各自的优缺点, 模块化的好处是各个模块都有自己明确的优化的目标, 可解释性较强, 且容易debug, 缺点是各个模块优化的目标并不是最终的驾…

智能电销机器人,主要体现的价值是什么

21世纪科技的迅速发展&#xff0c;人工智能逐渐走入大家的视线&#xff0c;越来越多的机器人出现在我们生活中。见的最多的有电销公司的智能语音机器人、在仓库拣货打包的机器人、商场店铺供娱乐对话的机器人。机器人活跃在各行各业中&#xff0c;降低了人工成本&#xff0c;代…

Realsense D435i实时运行ORB-SLAM3

三、ORB-SLAM3的ROS编译&#xff08;Realsense D435i实时跑ORB-SLAM3&#xff09; 四、ORB-SLAM3的ROS运行 3. ROS运行单目demo 创建ROS工作空间,初始化 mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin_make source devel/setup.bash echo "source ~/catkin_ws/devel/…

人生的回忆

回忆是人类宝贵的精神财富&#xff0c;它们像一串串珍珠&#xff0c;串联起我们生活中的每一个片段。 回忆是时间的见证者&#xff0c;它们承载着我们成长、经历、悲欢离合的点点滴滴。 回忆让我们重温过去的欢笑与眼泪&#xff0c;感受那些已经逝去的时光。它们就像一本翻开的…

Jmeter(三十一):制造大批量的用户数据数据

需求&#xff1a;因测试需要&#xff0c;要造100w用户数据&#xff0c;通过用户名、手机号、密码可新增用户&#xff0c;其中用户名和电话号码要求100w用户不能重复 要点&#xff1a; 1、通过Bean shell Sampler实现用户名和手机号的足够随机。 符合我们常用规则的手机号&#…