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

[Qt]事件-鼠标事件、键盘事件、定时器事件、窗口改变事件、事件分发器与事件过滤器

目录

前言:Qt与操作系统的关系

一、Qt事件

1.事件介绍

2.事件的表现形式

常见的Qt事件:

常见的事件描述:

3.事件的处理方式

处理鼠标进入和离开事件案例

控件添加到对象树底层原理

二、鼠标事件

1.鼠标按下和释放事件(单击)

2.鼠标双击事件

3.鼠标移动事件

4.鼠标滚轮滚动事件

三、键盘事件 

1.键盘按下单个按键事件

2.组合键按下事件

四、定时器事件

使用说明

Demo:设置倒计时程序 

五、窗口相关事件

1.窗口移动事件

2.窗口大小改变事件

六、事件分发器与事件过滤器


前言:Qt与操作系统的关系

        Qt与操作系统的关系,虽然说Qt是一个跨平台的C++开发框架,但是Qt的很多能力其实都是操作系统提供的,而且Qt应用程序也是运行在操作系统上的,也需要操作系统的支持。只不过是Qt封装了系统调用的API而已,不同平台下封装不同的系统调用,实现了跨平台的能力。

        对于事件、文件操作、多线程编程、网络编程等模块的编程下,Qt也是无法独立完成的,一定是需要操作系统的支持,所以Qt的很多业务实现都需要操作系统提供很多的帮助。

一、Qt事件

1.事件介绍

        对于信号槽来说,用户进行的各种操作都可能会产生信号,可以给信号绑定槽函数,那么当信号触发的时候,就会自动的调用执行对应的槽函数了。事件和信号槽很相似,用户进行各种操作的时候,也会产生事件,同样可以给事件关联上处理函数或者说处理逻辑,当事件触发的时候,就能够执行对应的函数/逻辑了。

        信号槽机制是Qt的机制,而事件是操作系统的概念,Qt同样把操作系统的事件机制进行了封装,就变成了Qt的事件机制,而信号槽机制其实也就是Qt事件的更一步的封装机制。在实际开发当中绝大多数的情况,都是使用Qt的信号槽机制进行交互的。

        但是会有一些特殊情况,可能用户的一些行为操作,Qt中没有提供对的信号,也就没法关联信号槽了,此时就需要通过重写事件处理函数的形式,来手动处理事件的相应逻辑了。所以说事件机制可以让程序员根据实际的需求,更加深度化的去定制用户操作对应的处理逻辑了。

2.事件的表现形式

        Qt中的是使用一个对象来表示一个事件的,所有的Qt事件类都是继承于QEvent抽象类。事件的发出是通过操作系统或者Qt平台本身在代码逻辑下发出的。一些事件是由用户操作后发出,例如按下键盘,按下鼠标等。还有一些事件是由程序或系统本身发出的,例如定时器事件等。

常见的Qt事件:

        对于不同的事件关注的点是不一样的,所以说类内部的实现提供的接口方法也是不一样的。 

常见的事件描述:
事件说明
鼠标事件鼠标左键、鼠标右键等各种按键、鼠标滚轮、鼠标移动、按键的按下和松开
键盘事件      按键类型、按键按下和松开
定时器事件定时事件到达
进入离开事件  鼠标进入和离开区域
滚轮事件鼠标滚轮滚动
绘屏事件重绘屏幕的某些部分
显示隐藏事件窗口的显示和隐藏
移动事件窗口位置的变化
窗口事件是否为当前窗口
大小改变事件窗口大小改变
焦点事件键盘焦点的移动

3.事件的处理方式

        对于信号来说是定义槽函数并和信号进行关联,而事件的处理不太一样,需要重写该事件的处理函数来实现事件的处理。具体是使用多态的机制,创建子类,继承要监控的父类,在子类中重写事件处理函数,后续事件触发的时候,就会通过多态的机制,执行到重写的子类事件执行函数了。

        为什么非要创建子类,在子类中重写事件处理函数呢?因为对于每个控件的相同事件有着不同的处理逻辑,所以需要为每一个控件定制他自己独有的处理方法,当然所有控件用一个也是可以的,直接在QWidget类中重写事件处理函数就可以了,这样就会使所有的控件同一事件的处理操作一样了。

处理鼠标进入和离开事件案例

        首先创建子类,然后再子类中定义上图中的两个事件处理函数,enterEvent是鼠标进入事件,leaveEvent是鼠标离开事件。之后可以代码中创建我们的子类控件,也就是创建一个父类指针指向子类的对象,然后鼠标进入和离开通过多态机制,就会执行子类重写的函数了。

        也可以通过ui界面的方式,我们拖拽一个父类控件,然后把控件提升为一个子类控件,同时设置该控件的父类即可。原理和上述类似,就是把标准控件变为了标准控件的自定义子类控件,会继承标准控件的属性和功能。

控件添加到对象树底层原理

        创建一个QPushButton之后,他会调用QPushButton的构造函数,QPushButton继承于QAbstractButton,所以会调用QAbstractButton的构造函数,QAbstractButton继承于QWidget,所以对调用QWidget的构造函数,会一直层层调用,直到调用的QObject的时候位置,他是所有类的基类,那么调用之后,parent参数也层层传递给了QObject类,通过参数的值来判断是否要添加到对象树,以及添加到什么位置上。

二、鼠标事件

        Qt中的鼠标事件是由QMouseEvent类来实现的,当鼠标移动和操作都会产生鼠标事件。

1.鼠标按下和释放事件(单击)

        鼠标按下事件处理函数是mousePressEvent,鼠标释放事件处理函数是mouseReleaseEvent他带了一个event参数,内部就带有了鼠标的各种属性,例如鼠标点击/释放的位置、哪个按键点击/释放的等等。

        如何判断是操作的鼠标哪个键呢,Qt中提供了一些MouseButton枚举变量对应的就是鼠标的哪一个按键了。Qt::LeftButton左键、Qt::RightButton右键、Qt::MidButton鼠标滚轮按键。 

        对于mousePressEvent处理函数来说, 无论是鼠标的左键、右键、滚轮等等按键都能进行触发,但是对于一些游戏鼠标的特殊按键是不一定的,因为那些按键是通过特定的驱动程序转化为一些其他操作了,不一定是原生的鼠标点击操作。

        对于QPushButton的clicked()信号就是对应的一次鼠标按下和一次鼠标释放事件。

void Label::mousePressEvent(QMouseEvent *event)
{if(event->button() == Qt::LeftButton){qDebug() << "按下左键";}else if(event->button() == Qt::RightButton){qDebug() << "按下右键";}//当前ev对象,就包含了鼠标点击位置的坐标qDebug() << event->x() << ", " << event->y();//相对于屏幕左上角的坐标qDebug() << event->globalX() << ", " << event->globalY();
}void Label::mouseReleaseEvent(QMouseEvent *event)
{if(event->button() == Qt::LeftButton){qDebug() << "释放左键";}else if(event->button() == Qt::RightButton){qDebug() << "释放右键";}//当前ev对象,就包含了鼠标点击位置的坐标qDebug() << event->x() << ", " << event->y();//相对于屏幕左上角的坐标qDebug() << event->globalX() << ", " << event->globalY();
}

2.鼠标双击事件

         鼠标双击事件的处理函数是mouseDoubleClickEvent函数,使用方法和上述单击的没什么区别。对于双击左键的事件间隔是跟随系统的,当鼠标双击的时候,单击事件也会触发,当第一次点击的时候就会触发单击操作,第二次点击的时候会触发双击操作,所以如果处理不好可以会出问题。

3.鼠标移动事件

        鼠标移动的事件处理函数是mouseMoveEvent函数,所有的操作和上述也都是一样的,都是基于event参数进行的操作。但是我们实现完之后会发现,我们想在鼠标移动的时候打印鼠标所处的位置,却打印不出来,是为什么呢?

        因为鼠标移动不同于鼠标点击操作,因为鼠标移动会产生大量的事件,在进行一些复杂的程序的时候,一直触发鼠标移动事件会降低程序的效率,所以说为了保证效率,默认是不会对鼠标的移动进行追踪,也就是说鼠标移动的时候不会调用鼠标移动处理函数。如何打开追踪呢?

void setMouseTracking(bool enable);

        鼠标移动事件的追踪是有区域限制的,而且没有继承关系,如果说在QPushButton中设置的,那么QWidget的窗口是无法追踪的,如果在QWidegt窗口设置的,那么QPushButton是无法追踪的,但是这样的化QWidget也是无法追踪的,他会拦截事件。 

4.鼠标滚轮滚动事件

        鼠标滚轮滚动的事件处理函数是wheelEvent函数,他的参数不是QMouseEvent类型了,而是变成了一个QWheelEvent滚轮类。该类中保存了一个滚轮移动的距离,正数表示向前移动,负数表示向后移动,可以使用该类中的delta()函数来获取滚动的距离。

intQGraphicsSceneWheelEvent::delta() const;


三、键盘事件 

        Qt中的键盘事件是由QKeyEvent类来实现的,Qt中的QShortCut设置快捷键的类就是Qt信号槽机制封装过的一个用于获取键盘按键的一种方式。

        键盘事件和鼠标事件最大的不同在于,键盘事件的触发,首先需要窗口获得焦点之后,才会触发对应的键盘事件。

1.键盘按下单个按键事件

        键盘按下事件的处理函数是KeyPressEvent函数,函数中的参数就是键盘的各种属性内容,参数内部就包含了用户具体输入的内容了。 可以通过QKeyEvent类中的key函数获取到输入的内容。

        当我们打印key的返回值的时候,会发现我们输入的内容都变成了一些数字,在Qt中把键盘的所有按键都用一个枚举变量Key定义成了各种值的数字。使用Qt::xxx便是键盘按键。

void Widget::keyPressEvent(QKeyEvent *event)
{// 获取键盘输入按键int key = event->key();//判断键盘是否输入的是按键Aif(key == Qt::Key_A){qDebug() << "按下了A键";}
}

        上述的枚举值Key_A等是不会区分大小写的,键盘属于物理按键,而大小写属于的是字符的概念,通过检测键盘shift的状态来区分用户输入的大小写,而并非这些枚举变量值区分大小写。

2.组合键按下事件

        按下组合键也是属于键盘输入事件,也是由keyPressEvent函数进行事件处理,对于组合键一般都是ctrl、shift、alt等等组合操作。Qt内置了对于键盘输入是否使用了组合键的判断,并不是直接判断,而是把上述的ctrl、shift、alt等按键定义为了修改键,并为这些修改键定义了在了Qt内部的KeyboardModifiter枚举变量中。同时在QKeyEvent类中提供了modifiers函数用来判断是否使用了修改键,并返回修改键的值。通过判断是否使用修改键加上普通键,就可以判断出来是否使用了组合键了。

Qt::KeyboardModifiers modifiers() const;

void Widget::keyPressEvent(QKeyEvent *event)
{// 获取用户输入内容int key = event->key();// 判断是否是ctrl + Aif(key == Qt::Key::Key_A && event->modifiers() == Qt::ControlModifier){qDebug() << "按下了组合键 ctrl + A";}
}

四、定时器事件

        Qt中进行窗口程序的处理过程中,经常要周期性的执行某些操作,就需要用到定时器了,定时器会在一定时间间隔后,去执行某一个任务,这种机制在很多场景中都会用到。

使用说明

       在Qt中定时器事件类是QTimerEvent类。定时器事件的触发是由定时器完成的,那么如何创建定时器呢?QObject类中提供了startTimer函数,会创建一个定时器对象,同时启动定时器并返回一个定时器的唯一标识符对象,后续就用该标识符操作定时器了。QObject类还提供了关闭定时器的函数killTimer,传递的就是定时器的标识符。

        当定时器的计时到了一个周期之后,也就是到了设置的时间后,会触发定时器事件,timerEvent则是定时器定时器事件的处理函数,参数就是定时器事件。

int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);  // 启动定时器

void killTimer(int id);                                                                                   // 销毁定时器

        还需要注意的一点是,定时器在一个窗口/类中可以创建多个,而这些定时器想要实现的操作是不一样的,但是都会调用同一个定时器事件处理函数,所以在触发定时器事件后,首先要获取定时器事件的内部存放的定时器标识符,然后用if-else来确定需要执行什么操作。

        但是实际开发中一般都是使用封装好的QTimer类进行定时器的操作,当触发定时器事件的时候,会产生QTimer::timeout信号,之后绑定槽函数,实现定时器事件的处理会更方便一些。就不需要我们管理销毁定时器、以及区分是哪个定时器触发的事件了。

    QTimer *timer = new QTimer(this);    connect(timer, &QTimer::timeout, this, &MyWidget::handleTimeout);timer->start(1000); // 启动定时器
Demo:设置倒计时程序 

        创建一个LCDNumber控件和一个定时器,设置定时时间为1s,事件到了就调用定时器事件处理函数,在函数内部操作LCDNumber控件的值-1,就实现了倒计时。

int timerId() const { return id; }

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置初始值ui->lcdNumber->display(10);//开启定时器_timerId = this->startTimer(1000);
}Widget::~Widget()
{delete ui;
}//定时器事件处理函数
void Widget::timerEvent(QTimerEvent *event)
{//获取触发定时器事件是哪一个定时器if(event->timerId() != this->_timerId){return;}int value = ui->lcdNumber->intValue();if(value <= 0){this->killTimer(this->_timerId);return;}ui->lcdNumber->display(value - 1);
}

五、窗口相关事件

1.窗口移动事件

        窗口移动事件的的处理函数是moveEvent函数,会带有一个QMobeEvent类型的参数,该类内部最主要的接口就是oldPos和pos,分别代表的是旧的位置,和移动后的新位置。并返回QPoint类型的变量,内部就包含了x,y坐标系的值。

const QPoint& oldPos() coonst;

const QPoint& pos() const;

2.窗口大小改变事件

         窗口大小改变事件的处理函数是resizeEvent函数,参数是QResizeEvent,和窗口移动事件类似,类内部最主要的函数就是oldSize和size表示原来的大小和改变后的窗口大小。返回一个QSize类型的参数,内部包含了长度和宽度等数值,和上面的QSize合起来就是窗口的geomeory属性。

const QSize& oldSize() coonst;

const QSize& size() const;

六、事件分发器与事件过滤器

        事件分发和事件过滤也是属于Qt事件的机制之一,对于事件分发器来说,会重写一个event函数,会直接获取到所有的事件,并对这些事件在进行分发处理,但是这样很有很大的危险,如果说实现过程中某些逻辑不正确的化,可能会导致很多的事件无法处理,或者无法正确的处理,所以说还是推荐对每个事件单独重写事件处理函数,甚至说更推荐使用信号槽机制进行处理,除非Qt中没有对应的信号机制,在使用Qt的事件机制解决问题。

        事件过滤会比事件分发好一些,事件过滤器对于特定的一些事件就行事件处理,不会涉及到所有事件的重写操作。但也不推荐使用,也不常见。如果说一个程序在特定场景或特定操作中需要禁用用户的某些操作,可以考虑使用事件过滤机制。

        事件过滤器一般也是事件分发器使用的时候,搭配使用的一个机制,先过滤一些事件,然后再进行事件的分发处理。

相关文章:

[Qt]事件-鼠标事件、键盘事件、定时器事件、窗口改变事件、事件分发器与事件过滤器

目录 前言&#xff1a;Qt与操作系统的关系 一、Qt事件 1.事件介绍 2.事件的表现形式 常见的Qt事件&#xff1a; 常见的事件描述: 3.事件的处理方式 处理鼠标进入和离开事件案例 控件添加到对象树底层原理 二、鼠标事件 1.鼠标按下和释放事件&#xff08;单击&#x…...

关于机器学习的一份总结

在之前的文章中分别有详细的关于机器学习中某一学习算法的介绍&#xff0c;但缺少一个总体关于机器学习的总结&#xff0c;所以在这篇文中就是关于机器学习的一份总结。 在最近的日子中&#xff0c;人工智能日益火热起来&#xff0c;而机器学习是其中举足轻重的一部分&#xf…...

推荐一个开源的轻量级任务调度器!TaskScheduler!

大家好&#xff0c;我是麦鸽。 这次推荐一款轻量级的嵌入式任务调度器&#xff0c;目前已经有1.4K的star&#xff0c;这个项目比较轻量化&#xff0c;只有5个源文件&#xff0c;可以作为学习的一个开源项目。 核心文件 项目概述&#xff1a; 这是一个轻量级的协作式多任务处理&…...

【18】Word:明华中学-儿童医保❗

目录 题目​ NO2 NO3 NO4 NO5 NO6 NO7 NO8 NO9 题目 NO2 布局→页面设置对话框→纸张方向&#xff1a;横向→纸张大小&#xff1a;A3 &#xff1b;页面设置对话框&#xff1a;直接输入纸张大小的宽度和高度即可→页面设置对话框&#xff1a;上下左右边距→版式&…...

如何用selenium来链接并打开比特浏览器进行自动化操作(1)

前言 本文是该专栏的第76篇,后面会持续分享python爬虫干货知识,记得关注。 本文,笔者将基于“比特浏览器”,通过selenium来实现链接并打开比特浏览器,进行相关的“自动化”操作。 值得一提的是,在本专栏之前,笔者有详细介绍过“使用selenium或者pyppeteer(puppeteer)…...

基于springboot+thymeleaf+Redis仿知乎网站问答项目源码

项目介绍 基于springbootthymeleafRedis仿知乎网站问答项目源码&#xff0c;可以作为毕业设计项目参考学习 按照需要一定动手能力 发文章&#xff0c;发视频&#xff0c;发想法&#xff0c;提问回答&#xff0c;注册登录 开发环境 使用技术&#xff1a;springbootthymeleafRe…...

读spring官方文档的一些关键知识点介绍

目录 bean definitionBeanPostProcessorBeanFactoryPostProcessorComponent and Further Stereotype AnnotationsAOP Concepts bean definition https://docs.spring.io/spring-framework/docs/5.1.3.RELEASE/spring-framework-reference/core.html#beans-child-bean-definiti…...

2024年AI与大数据技术趋势洞察:跨领域创新与社会变革

目录 引言 技术洞察 1. 大模型技术的创新与开源推动 2. AI Agent 智能体平台技术 3. 多模态技术的兴起:跨领域应用的新风口 4. 强化学习与推荐系统:智能化决策的底层驱动 5. 开源工具与平台的快速发展:赋能技术创新 6. 技术安全与伦理:AI技术的双刃剑 7. 跨领域技…...

ThinkPhp项目解决静态资源请求的跨域问题的解决思路

背景&#xff1a;我在前端使用vue语言开发的&#xff0c;请求的后端是用ThinkPhp项目开发的。我vue项目里的请求php接口&#xff0c;自带header参数的跨域问题通过网上查询到的server端配置方法已经解决了。我使用的 是中间件的配置方法&#xff1a; <?php//admin 项目 配…...

mybatis的多对一、一对多的用法

目录 1、使用VO聚合对象&#xff08;可以解决这两种情况&#xff09; 多对一&#xff1a; 一对多&#xff1a; 2、非聚合的多对一做法&#xff1a; 3、非聚合的一对多做法&#xff1a; 1、使用VO聚合对象&#xff08;可以解决这两种情况&#xff09; 当我需要多对一、一对…...

消息队列实战指南:三大MQ 与 Kafka 适用场景全解析

前言&#xff1a;在当今数字化时代&#xff0c;分布式系统和大数据处理变得愈发普遍&#xff0c;消息队列作为其中的关键组件&#xff0c;承担着系统解耦、异步通信、流量削峰等重要职责。ActiveMQ、RabbitMQ、RocketMQ 和 Kafka 作为市场上极具代表性的消息队列产品&#xff0…...

前端发送Ajax请求的技术Axios

目录 1.引入Axios文件 2.使用Axios发送请求 2.1请求方法的别名 请求的URL地址怎么来的&#xff1f; 后端实现 前后端交互 1.引入Axios文件 <script src"https://unpkg.com/axios/dist/axios.min.js"></script> 2.使用Axios发送请求 2.1请求方法的…...

第17章:Python TDD回顾与总结货币类开发

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

opencv_KDTree_搜索介绍及示例

cv::flann::KDTreeIndexParams 说明&#xff0c;使用&#xff1f; cv::flann::KDTreeIndexParams 是 OpenCV 中用于配置 KD 树&#xff08;K-Dimensional Tree&#xff09;索引参数的类。KD 树是一种用于多维空间中的点搜索的数据结构&#xff0c;常用于最近邻搜索等问题。在…...

Windows 上安装 MongoDB 的 zip 包

博主介绍&#xff1a; 大家好&#xff0c;我是想成为Super的Yuperman&#xff0c;互联网宇宙厂经验&#xff0c;17年医疗健康行业的码拉松奔跑者&#xff0c;曾担任技术专家、架构师、研发总监负责和主导多个应用架构。 近期专注&#xff1a; RPA应用研究&#xff0c;主流厂商产…...

先进制造aps专题二十七 西门子opcenter aps架构分析

欧美的商业aps&#xff0c;主要就是sap apo,西门子opcenter aps,达索quintiq 从技术的层面&#xff0c;西门子aps是不如sap apo的&#xff0c;但是西门子aps是西门子数字化工厂产品的核心&#xff0c;有很多特色&#xff0c;所以分析 西门子aps主要分计划器和排产器两个部分 计…...

【数据分享】1929-2024年全球站点的逐年平均气温数据(Shp\Excel\无需转发)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…...

机器学习——什么是代价函数?

1.代价函数的定义 首先,提到代价函数是估计值和实际值的差,这应该是指预测值和真实值之间的差异,用来衡量模型的好坏。 在一元线性模型中,模型是直线,有两个参数,可能是斜率和截距。 通过调整这两个参数,让代价函数最小,这应该是说我们要找到最佳的斜率和截距,使得预测…...

docker 部署 MantisBT

1. docker 安装MantisBT docker pull vimagick/mantisbt:latest 2.先运行实例&#xff0c;复制配置文件 docker run -p 8084:80 --name mantisbt -d vimagick/mantisbt:latest 3. 复制所需要配置文件到本地路径 docker cp mantisbt:/var/www/html/config/config_inc.php.…...

02内存结构篇(D1_自动内存管理)

目录 一、内存管理 1. C/C程序员 2. Java程序员 二、运行时数据区 1. 程序计数器 2. Java虚拟机栈 3. 本地方法栈 4. Java堆 5. 方法区 运行时常量池 三、Hotspot运行时数据区 四、分配JVM内存空间 分配堆的大小 分配方法区的大小 分配线程空间的大小 一、内存管…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

React核心概念:State是什么?如何用useState管理组件自己的数据?

系列回顾&#xff1a; 在上一篇《React入门第一步》中&#xff0c;我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目&#xff0c;并修改了App.jsx组件&#xff0c;让页面显示出我们想要的文字。但是&#xff0c;那个页面是“死”的&#xff0c;它只是静态…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...