当前位置: 首页 > news >正文

【Qt学习】02:信号和槽机制

信号和槽机制


OVERVIEW

  • 信号和槽机制
      • 一、系统自带信号与槽
      • 二、自定义信号与槽
        • 1.基本使用
          • student.cpp
          • teacher.cpp
          • widget.cpp
          • main.cpp
        • 2.信号与槽重载
          • student.cpp
          • teacher.cpp
          • widget.cpp
          • main.cpp
        • 3.信号连接信号
        • 4.Lambda表达式
        • 5.信号与槽总结

信号槽机制是 Qt 框架引以为豪的机制之一。

所谓信号槽实际就是观察者模式,将要处理的信号自己的一个函数/槽slot绑定来处理信号,当某个事件发生之后检测对象就会发出信号(无目的的广播),如果有其他对象对这个信号感兴趣就会使用connect函数进行连接。

即当信号发出时,被连接的槽函数会自动被回调。类似观察者模式:当发生了感兴趣的事件,某个操作就会被自动触发。

一、系统自带信号与槽

信号槽的优点:松散耦合,信号发送方和接收方本身是没有关联的,通过connect连接将两端耦合在一起

QPushButton * quitBtn = new QPushButton("quit",this);//创建关闭按钮
connect(quitBtn, &QPushButton::clicked, this, &QWidget::close);//信号槽使用方式

函数connect(sender, signal, receiver, slot);参数解释:

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

利用帮助文档了查找系统自带的信号和槽,在帮助文档中如按钮的点击信号输入QPushButton,首先我们可以在Contents中寻找关键字 signals信号的意思,但是我们发现并没有找到,这时候我们应该想到也许这个信号的被父类继承下来的,因此我们去他的父类QAbstractButton中就可以找到该关键字,点击signals索引到系统自带的信号有如下几个。

这里的clicked就是我们要找到,槽函数的寻找方式和信号一样,只不过他的关键字是slot。

二、自定义信号与槽

使用connect可使用系统提供的信号和槽,

但Qt的信号槽机制并不仅仅是使用系统提供那部分,其还允许开发者设计自己的信号和槽,

1.基本使用

student.cpp
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject {Q_OBJECT
public:explicit Student(QObject *parent = nullptr);
signals:public slots://槽函数slot 返回值是void 需要声明需要实现 可以有参数(发生重载)void treat();
};#endif // STUDENT_H
#include "student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent) { }void Student::treat() {qDebug() << "debug: receive signal. student treats teacher.";
}
teacher.cpp
#ifndef TEACHER_H
#define TEACHER_H#include <QObject>class Teacher : public QObject {Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);
signals://信号signal 返回值是void 只需要声明不需要实现 可以有参数(发生重载)void hungry();
public slots:};#endif // TEACHER_H
#include "teacher.h"Teacher::Teacher(QObject *parent) : QObject(parent) { }
widget.cpp
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "teacher.h"
#include "student.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECT
public:Widget(QWidget *parent = nullptr);~Widget();void classIsOver();
private:Ui::Widget *ui;Teacher *tch;Student *stu;
};#endif // WIDGET_H
#include <QPushButton>
#include <QDebug>
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//1.第一次绑定 使用系统自带信号与槽函数QPushButton *mybtn = new QPushButton("myBtn", this);mybtn->resize(100, 30);connect(mybtn, &QPushButton::clicked, this, &Widget::classIsOver);//按钮触发classIsOver函数//2.第二次绑定 使用自定义信号与槽函数tch = new Teacher(this);//初始化老师对象stu = new Student(this);//初始化学生对象connect(tch, &Teacher::hungry, stu, &Student::treat);//老师饿了时学生主动请客的connect连接
}Widget::~Widget() {delete ui;
}void Widget::classIsOver() {qDebug() << "debug: btn is pushed and Widget::classIsOver was called. emitting signal...";emit tch->hungry();//函数被调用 则触发发送老师饿了的信号
}
main.cpp
#include <QApplication>
#include "widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

在这里插入图片描述

2.信号与槽重载

student.cpp
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject {Q_OBJECT
public:explicit Student(QObject *parent = nullptr);
signals:public slots://槽函数slot 返回值是void 需要声明需要实现 可以有参数(发生重载)void treat();void treat(QString food);
};#endif // STUDENT_H
#include "student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent) { }void Student::treat() {qDebug() << "debug: receive signal. student treats teacher.";
}void Student::treat(QString food) {qDebug() << "debug: receive signal. student treats teacher with " << food.toUtf8().data();
}
teacher.cpp
#ifndef TEACHER_H
#define TEACHER_H#include <QObject>class Teacher : public QObject {Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);
signals://信号signal 返回值是void 只需要声明不需要实现 可以有参数(发生重载)void hungry();void hungry(QString food);
public slots:};#endif // TEACHER_H
#include "teacher.h"Teacher::Teacher(QObject *parent) : QObject(parent) { }
widget.cpp
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "teacher.h"
#include "student.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECT
public:Widget(QWidget *parent = nullptr);~Widget();void classIsOver1();void classIsOver2();
private:Ui::Widget *ui;Teacher *tch;Student *stu;
};#endif // WIDGET_H
#include <QPushButton>
#include <QDebug>
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//1.第一次绑定 使用系统自带信号与槽函数QPushButton *mybtn1 = new QPushButton("myBtn1", this);mybtn1->resize(100, 30);connect(mybtn1, &QPushButton::clicked, this, &Widget::classIsOver1);//按钮触发classIsOver函数QPushButton *mybtn2 = new QPushButton("myBtn2", this);mybtn2->move(100, 0);mybtn2->resize(100, 30);connect(mybtn2, &QPushButton::clicked, this, &Widget::classIsOver2);//按钮触发classIsOver函数tch = new Teacher(this);//初始化老师对象stu = new Student(this);//初始化学生对象//2.第二次绑定 使用自定义信号与槽函数void(Teacher::*tchsignal_)() = &Teacher::hungry;void(Student::*stusignal_)() = &Student::treat;connect(tch, tchsignal_, stu, stusignal_);//老师饿了时学生主动请客的connect连接//3.第三次绑定 使用自定义信号与槽函数//定义函数指针 用于识别重载的函数地址void(Teacher::*tchsignal)(QString) = &Teacher::hungry;void(Student::*stusignal)(QString) = &Student::treat;connect(tch, tchsignal, stu, stusignal);
}Widget::~Widget() {delete ui;
}void Widget::classIsOver1() {qDebug() << "debug: btn1 is pushed and Widget::classIsOver1 was called. emitting signal...";emit tch->hungry();//函数被调用 则触发发送老师饿了的信号
}void Widget::classIsOver2() {qDebug() << "debug: btn2 is pushed and Widget::classIsOver2 was called. emitting signal...";emit tch->hungry("apple pie");
}
main.cpp
#include <QApplication>
#include "widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

在这里插入图片描述

3.信号连接信号

之前的使用中都是利用槽函数实现的,点击btn按钮触发函数调用,函数调用后emit发出信号再触发slot槽函数,从而实现连续的效果。

也可以使用另一种方式信号触发信号完成,利用点击btn按钮的信号去触发另一个信号,

主要对widget.cpp中的内容进行修改,修改后如下:

#include <QPushButton>
#include <QDebug>
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//1.第一次绑定 使用系统自带信号与槽函数QPushButton *mybtn1 = new QPushButton("myBtn1", this);mybtn1->resize(100, 30);//connect(mybtn1, &QPushButton::clicked, this, &Widget::classIsOver1);//按钮触发classIsOver函数QPushButton *mybtn2 = new QPushButton("myBtn2", this);mybtn2->move(100, 0);mybtn2->resize(100, 30);//connect(mybtn2, &QPushButton::clicked, this, &Widget::classIsOver2);//按钮触发classIsOver函数tch = new Teacher(this);//初始化老师对象stu = new Student(this);//初始化学生对象//2.第二次绑定 使用自定义信号与槽函数void(Teacher::*tchsignal_)() = &Teacher::hungry;void(Student::*stusignal_)() = &Student::treat;connect(tch, tchsignal_, stu, stusignal_);//老师饿了时学生主动请客的connect连接connect(mybtn1, &QPushButton::clicked, tch, tchsignal_);//信号连接信号//3.第三次绑定 使用自定义信号与槽函数//定义函数指针 用于识别重载的函数地址void(Teacher::*tchsignal)(QString) = &Teacher::hungry;void(Student::*stusignal)(QString) = &Student::treat;connect(tch, tchsignal, stu, stusignal);//connect(mybtn2, &QPushButton::clicked, tch, tchsignal);//信号连接信号connect(mybtn2, &QPushButton::clicked, this, [=](){emit tch->hungry("apple pie");});
}Widget::~Widget() {delete ui;
}void Widget::classIsOver1() {qDebug() << "debug: btn1 is pushed and Widget::classIsOver1 was called. emitting signal...";emit tch->hungry();//函数被调用 则触发发送老师饿了的信号
}void Widget::classIsOver2() {qDebug() << "debug: btn2 is pushed and Widget::classIsOver2 was called. emitting signal...";emit tch->hungry("apple pie");
}

在这里插入图片描述

btn触发信号连接信号,跳过了classIsOver函数的中间调用过程,直接实现了最终结果的输出。

4.Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名的函数对象以简化编程工作,Lambda表达式的基本构成:

[capture](parameters)mutable->returnType {statement
}
  1. 函数对象参数;[],标识一个Lambda的开始,这部分必须存在不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:

    • void,没有使用任何函数对象参数。
    • =,函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)
    • &,函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)
    • this,函数体内可以使用Lambda所在类中的成员变量
    • a,将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符
    • &a,将a按引用进行传递
    • a, &b,将a按值进行传递,b按引用进行传递。
    • =,&a, &b,除a和b按引用进行传递外,其他参数都按值进行传递。
    • &, a, b,除a和b按值进行传递外,其他参数都按引用进行传递。
  2. 操作符重载函数参数;标识重载的 () 操作符的参数,没有参数时这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递

  3. 可修改标示符;mutable 声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)

    QPushButton * myBtn = new QPushButton (this);
    QPushButton * myBtn2 = new QPushButton (this);
    myBtn2->move(100,100);
    int m = 10;connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });
    connect(myBtn2,&QPushButton::clicked,this,[=] ()  { qDebug() << m; });
    qDebug() << m;
    
  4. 函数返回值;-> 返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

  5. 是函数体;{},标识函数的实现这部分不能省略,但函数体可以为空。

利用Lambda表达式简化信号与槽的使用机制:利用lambda表达式实现点击按钮,关闭窗口:

QPushButton *btn = new QPushButton;
btn->setText("quit");
connect(btn, &QPushButton::clicked, this, [=](){this->close();
});

5.信号与槽总结

在这里插入图片描述

自定义信号槽需要注意的事项:

  1. 发送者和接收者都需要是QObject的子类(槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
  2. 自定义信号signal返回值是 void,只需要声明不需要实现,可以有参数(发生重载)
  3. 槽函数是普通的成员函数,需要声明也需要实现,会受到 public、private、protected 的影响(早期必须写到public slots作用域下)
  4. 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数

信号与槽的连接:connect函数

  1. 一个信号可以和多个槽函数相连:如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的
  2. 多个信号可以连接到一个槽:只要任意一个信号发出,这个槽就会被调用
  3. 一个信号可以连接到另外的一个信号:当第一个信号发出时第二个信号被发出,除此之外这种信号-信号的形式和信号-槽的形式没有什么区别。
  4. 信号槽要求信号和槽的参数类型对应(参数的个数信号可以多于槽函数,反之报错)
  5. 若信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。
  6. 槽可以被取消链接:这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽
  7. 使用Lambda 表达式:在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的,在连接信号和槽的时候,槽函数可以使用Lambda表达式的方式进行处理。

QT4版本的信号槽写法:Qt5在语法上完全兼容Qt4。

connect(tch, SIGNAL(hungry(QString)), stu, SLOT(treat(QString)));

这里使用了SIGNAL和SLOT这两个宏,将两个函数名转换成了字符串。注意到connect函数的signal和slot都是接受字符串,一旦出现连接不成功的情况,Qt4是没有编译错误的(因为一切都是字符串编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增加程序的不稳定性。

相关文章:

【Qt学习】02:信号和槽机制

信号和槽机制 OVERVIEW 信号和槽机制一、系统自带信号与槽二、自定义信号与槽1.基本使用student.cppteacher.cppwidget.cppmain.cpp 2.信号与槽重载student.cppteacher.cppwidget.cppmain.cpp 3.信号连接信号4.Lambda表达式5.信号与槽总结 信号槽机制是 Qt 框架引以为豪的机制之…...

软件工程(十三) 设计模式之结构型设计模式(一)

前面我们记录了创建型设计模式,知道了通过各种模式去创建和管理我们的对象。但是除了对象的创建,我们还有一些结构型的模式。 1、适配器模式(Adapter) 简要说明 将一个类的接口转换为用户希望得到的另一个接口。它使原本不相同的接口得以协同工作。 速记关键字 转换接…...

Node与Express后端架构:高性能的Web应用服务

在现代Web应用开发中&#xff0c;后端架构的性能和可扩展性至关重要。Node.js作为一个基于事件驱动、非阻塞I/O的平台&#xff0c;以及Express作为一个流行的Node.js框架&#xff0c;共同构建了高性能的Web应用服务。 在本文中&#xff0c;我们将深入探讨Node与Express后端架构…...

C++炸弹小游戏

游戏效果 小人可以随便在一些元素&#xff08;如石头&#xff0c;岩浆&#xff0c;水&#xff0c;宝石等&#xff09;上跳跃&#xff0c;“地面”一直在上升&#xff0c;小人上升到顶部或者没有血的时候游戏结束&#xff08;初始20点血&#xff09;&#xff0c;小人可以随意放炸…...

发送通知消息

目录 1 himall3.0商城源码 1.1 SendMessageOnOrderShipping 1.1.1 //发送通知消息 1.2 /// 所有订单是否都支付 1.2.1 //有待付款的订单&#xff0c;则未支付完成 himall3.0商城源码 public static List<InvoiceTitleInfo> GetInvoiceTitles(long userid) { re…...

Python报错:PermissionError: [Errno 13] Permission denied解决方案

Python报错&#xff1a;PermissionError: [Errno 13] Permission denied 翻译为&#xff1a;权限错误&#xff1a;[errno 13]权限被拒绝 错误产生的原因是文件无法打开&#xff0c;可能产生的原因是文件找不到&#xff0c;或者被占用&#xff0c;或者无权限访问&#xff0c;或者…...

【leetcode】第六章 二叉树part01

递归遍历 144. 二叉树的前序遍历 // 前序遍历 public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res new ArrayList<>();preOrder(root, res);return res;}private void preOrder(TreeNode root, List<Integer> res) {if (ro…...

All In One!Meta发布SeamlessM4T,支持100种语言,35种语音、开源、在线体验!

多语言识别翻译的研究一直都是学术界研究的重点。目前全球有几千种语言&#xff0c;在全球化背景下不同语言人群之间的交流越来越密切&#xff0c;然而学习一门外语的成本是非常大的。前两年的研究主要集中在一对一、一对多的研究&#xff0c;然而当面对这么多的语言时&#xf…...

Python可视化工具库实战

Matplotlib Matplotlib 是 Python 的可视化基础库&#xff0c;作图风格和 MATLAB 类似&#xff0c;所以称为 Matplotlib。一般学习 Python 数据可视化&#xff0c;都会从 Matplotlib 入手&#xff0c;然后再学习其他的 Python 可视化库。 Seaborn Seaborn 是一个基于 Matplo…...

编解码视频测试序列集

最近测试解码器性能&#xff0c;搜集了一下可以免费的测试序列及&#xff0c;现在罗列如下&#xff0c;有很多需要翻墙&#xff1a; 1、h264的视频测试序列集 https://pi4.informatik.uni-mannheim.de/~kiess/test_sequences/download/ 2、HEVC测试序列 https://blog.csdn.net/…...

1 Hadoop入门

1.Hadoop是什么&#xff1f; (1)Hadoop是一个由Apache基金会所开发的分布式系统基础架构。 (2)主要解决&#xff0c;海量数据的存储和海量数据的分析计算问题。 (3)广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念——Hadoop生态圈 2.Hadoop的优势 3 Hadoop组成 4 HDF…...

骨传导耳机哪款比较好,市面上最好的骨传导耳机分享

随着科技的日新月异&#xff0c;骨传导耳机也在不断更新换代。市场上涌现出许多品牌&#xff0c;这使得消费者在购买时感到困惑。别担心&#xff01;我们为你整理了一些市场上最好的骨传导耳机品牌&#xff0c;希望能帮到你。现在&#xff0c;就让我们一起探索这些骨传导耳机的…...

centos7安装docker-compose—及常见错误排解

目录 一、Docker-Compose概述Compose有2个重要的概念&#xff1a;一、安装docker-compose1.从github上下载docker-compose二进制文件安装 二、Docker-compose实战 二、Dcoker-compose 不好下载&#xff0c;你直接使用docker 一个一个的安装使用dockerfile安装各种服务组件 一、…...

Stable Diffusion 文生图技术原理

图像生成模型简介 图片生成领域来说&#xff0c;有四大主流生成模型&#xff1a;生成对抗模型&#xff08;GAN&#xff09;、变分自动编码器&#xff08;VAE&#xff09;、流模型&#xff08;Flow based Model&#xff09;、扩散模型&#xff08;Diffusion Model&#xff09;。…...

Jumpserver堡垒机管理(安装和相关操作)-------从小白到大神之路之学习运维第89天

第四阶段 时 间&#xff1a;2023年8月28日 参加人&#xff1a;全班人员 内 容&#xff1a; Jumpserver堡垒机管理 目录 一、堡垒机简介 &#xff08;一&#xff09;运维常见背黑锅场景 &#xff08;二&#xff09;背黑锅的主要原因 &#xff08;三&#xff09;解决背黑…...

伦敦金走势多变怎么办

投资知识比较丰富的朋友&#xff0c;应该知道一个品种的价格过于波动&#xff0c;对投资者来说并是一件不友好的事情&#xff0c;因为频繁的价格变化&#xff0c;对于收益的稳定性会产生负面的影响&#xff0c;也可能让投资者的持仓陷入进退维谷的尴尬境地。 黄金作为贵金属市场…...

MybatisPlus-插件篇

文章目录 一、前言二、插件1、分页插件2.1.1、引入依赖2.1.1、配置分页插件2.1.3、使用分页方法 2、乐观锁插件2.1、引入依赖2.2、添加版本字段2.3、配置乐观锁插件2.4、执行更新操作 三、总结 一、前言 本文将详细介绍mybatisplus中常用插件的使用。 二、插件 1、分页插件 …...

数学建模:熵权法

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 熵权法 构建原始矩阵 D a t a Data Data 形状为 m ∗ n m *n m∗n &#xff0c;其中 m m m 为评价对象&#xff0c; n n n 为评价指标。对 D a t a Data Data矩阵的指标进行正向化处理&#xff0c;得到…...

软件测试实训系统建设方案

一 、系统概述 软件测试实训系统是软件开发过程中的一项重要测试活动&#xff0c;旨在验证不同软件模块或组件之间的集成与交互是否正常。综合测试确保各个模块按照设计要求正确地协同工作&#xff0c;以实现整个软件系统的功能和性能。以下是软件测试实训系统的一般流程和步骤…...

部署 ssm 项目到云服务器上(购买云服务器 + 操作远程云服务器 + 服务器中的环境搭建 + 部署项目到服务器)

部署 Web 项目 1、获取 Linux 环境1.1、如何去买一个云服务器1.2、远程操作云服务器1.3、在 Linux 系统中搭建 Java Web 的运行环境。1&#xff09;安装 JDK&#xff08;使用包管理器 yum 来安装&#xff09;2&#xff09; 安装Tomcat3&#xff09;安装 MySQL。 1.4、在云服务器…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...