嵌入式养成计划-45----QT--事件机制--定时器事件--键盘事件和鼠标事件--绘制事件
一百一十五、事件机制
- 当这件事情发生时,会自动走对应的函数处理(重写的事件函数)
115.1 事件处理简介
- 什么是事件? (重点)
- 件是由窗口系统或者自身产生的,用以响应所发生的各类事情,
- 比如用户按下并释放了键盘或者鼠标、窗口因暴露而需要重绘、定时器到时而应有所动作,等等
- 从某种意义上讲,事件比信号更原始,甚至可以认为大多数信号其实都是由事件产生的。
- 比如一个下压式按钮首先感受到的是鼠标事件,在进行必要的处理以产生按钮下沉继而弹起的视觉效果之后,才会发射 clicked()信号
- 如何处理事件? (重点)
- myWnd(自定义类) -继承-> QWidget -继承-> QObject
- 当事件发生时,首先被调用的是QObject类中的虚函数event(),
其 QEvent型参数标识了具体的事件类型bool QObject:: event (QEvent* e) {if (e == mouseEvent){void QWidget::mousePressEvent (QMouseEvent* e)void QWidget:: mouseReleaseEvent (QMouseEvent* e)}if(e == keyEvent){void QWidget::keyPressEvent (QMouseEvent* e)void QWidget:: keyReleaseEvent (QMouseEvent* e)} }
- 作为QObject类的子类, QWidget类覆盖了其基类中的
event()虚函数,并根据具体事件调用具体事件处理函数void QWidget::mousePressEvent (QMouseEvent* e) void QWidget::mouseReleaseEvent (QMouseEvent* e) void QWidget::keyPressEvent (QMouseEvent* e) void QWidget:: keyReleaseEvent (QMouseEvent* e) void QWidget::paintEvent (QPaintEvent* e)
- 而这些事件处理函数同样也是虚函数,也可以被 QWidget类的子类覆盖,以提供针对不同窗口部件类型的事件处理
- 组件的使用者所关心的往往是定义什么样的槽处理什么样的信号,而组件的实现者更关心覆盖哪些事件处理函数
115.2 事件处理函数由来
QObject类 提供了那些可以重写的虚函数[virtual] bool QObject::event(QEvent *e) // 参数:事件的类型QWidgets类, 提供了那些可以重写的虚函数[override virtual protected] bool QWidget::event(QEvent *event)[virtual protected] void QWidget::keyPressEvent(QKeyEvent *event)[virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event)[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)[virtual protected] void QObject::timerEvent(QTimerEvent *event)QPainter类 ---> 画家类void SimpleExampleWidget::paintEvent(QPaintEvent *){QPainter painter(this);painter.setPen(Qt::blue);painter.setFont(QFont("Arial", 30));painter.drawText(rect(), Qt::AlignCenter, "Qt");}
一百一十六、定时器事件
-
qt的定时器事件提供了两这种实现方式,分别是 基于对象版本 和 基于事件处理函数
-
基于事件处理函数
1.不需要手动书写信号函数,不需要写信号和槽 2.使用的是自己的成员函数,启动定时器函数、关闭定时器函数、定时器时间超时时的函数 3.功能:让系统在每隔一定的时间,自动执行某段代码 4.所需要的函数:startTimer(int sec); //自身的成员函数,表示启动一个定时器,给定毫秒,返回定时器的idkillTimer(int id);//自身的成员函数,表示关闭一个定时器,给定定时器idtimerEvent(QTimerEvent *e); //定时器处理的函数,表示定时器给定的时间到了,就自动执行该函数的内容
-
ui界面:
- 示例 :
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); } Widget::~Widget() {delete ui; } //启动按钮对应的槽函数处理 void Widget::on_startBtn_clicked() {if(ui->startBtn->text() == "启动"){//启动一个定时器tId = startTimer(1000);//将按钮文本设置成关闭ui->startBtn->setText("关闭");}else{//关闭一个定时器killTimer(tId);//将文本设置成启动ui->startBtn->setText("启动");} } //时间事件的函数处理 void Widget::timerEvent(QTimerEvent *e) {//判断哪个定时器超时if(e->timerId() == tId){ // static int num = 0; // ui->timeLab->setNum(++num);QTime sys_time = QTime::currentTime(); //获取当前系统时间//把系统时间转换成字符串QString s = sys_time.toString("hh::mm::ss");//将系统时间放入标签中ui->timeLab->setText(s);//居中显示ui->timeLab->setAlignment(Qt::AlignCenter);} }
- 示例 :
-
基于对象版本
- 需要用QTimer定时器类实例化一个对象
- 用对象调用启动定时器函数:start(int sec),让系统每隔sec毫秒,触发一个信号timeout
- 我们可以将timeout信号与自定义的槽函数连接,处理槽函数的逻辑代码
- 用对象调用关闭定时器函数: stop()
- 示例 :
//启动2对应的槽函数处理 void Widget::on_startBtn2_clicked() {if(ui->startBtn2->text() == "启动"){//启动一个定时器t->start(1000); //每隔1秒发射一个timeout信号//将启动按钮设置成关闭ui->startBtn2->setText("关闭");}else{//关闭一个定时器t->stop();//将关闭按钮设置成启动ui->startBtn2->setText("启动");} } //定时器超时对应的槽函数处理 void Widget::timeOut_Slot() {QTime sys_time = QTime::currentTime(); //获取当前系统时间//把系统时间转换成字符串QString s = sys_time.toString("hh-mm-ss");//将系统时间放入标签中ui->timeLab2->setText(s);//居中显示ui->timeLab2->setAlignment(Qt::AlignCenter); }
一百一十七、键盘事件和鼠标事件
- 当程序员使用键盘或者鼠标,系统就会自动调用QWidget中的对应事件处理函数
- 键盘事件和鼠标事件的函数原型
[virtual protected] void QWidget::keyPressEvent(QKeyEvent *event); //键盘按下事件函数 [virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event);//键盘抬起事件函数[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event);//鼠标双击事件函数 [virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)//鼠标移动事件函数 [virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)//鼠标按下事件函数 [virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)//鼠标抬起事件函数
117.1 键盘事件
- UI界面
代码示例 : - 头文件:
#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QKeyEvent> //键盘事件类 #include<QDebug>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECT public:Widget(QWidget *parent = nullptr);~Widget();void keyPressEvent(QKeyEvent *event) override; //键盘按下的重写事件函数声明void keyReleaseEvent(QKeyEvent *event) override;//键盘抬起的重写事件函数声明 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); } Widget::~Widget() {delete ui; } //重写键盘按下事件函数的实现 void Widget::keyPressEvent(QKeyEvent *event) {ui->label->setText(event->text()+":被按下");ui->label->setAlignment(Qt::AlignCenter);//判断哪个键被按下switch (event->key()){case 'W':{if(ui->label->y() < 0-ui->label->height()) //判断标签y轴是否完全出界面{ui->label->move(ui->label->x(), this->height()); //移动到界面的下面}ui->label->move(ui->label->x(), ui->label->y()-1);}} } //重写键盘抬起事件函数的实现 void Widget::keyReleaseEvent(QKeyEvent *event) {ui->label->setText(event->text()+":被抬起");ui->label->setAlignment(Qt::AlignCenter); }
117.2 鼠标事件
- 源文件:
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//窗口开启追踪功能this->setMouseTracking(true); } Widget::~Widget() {delete ui; } //重写键盘按下事件函数的实现 void Widget::keyPressEvent(QKeyEvent *event) {ui->label->setText(event->text()+":被按下");ui->label->setAlignment(Qt::AlignCenter);//判断哪个键被按下switch (event->key()){case 'W':{if(ui->label->y() < 0-ui->label->height()) //判断标签y轴是否完全出界面{ui->label->move(ui->label->x(), this->height()); //移动到界面的下面}ui->label->move(ui->label->x(), ui->label->y()-1);}} } //重写键盘抬起事件函数的实现 void Widget::keyReleaseEvent(QKeyEvent *event) {ui->label->setText(event->text()+":被抬起");ui->label->setAlignment(Qt::AlignCenter); } //鼠标按下重写事件函数的实现 void Widget::mousePressEvent(QMouseEvent *event) {if(event->button() == Qt::LeftButton){QString s = QString("左键被按下\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);}else if(event->button() == Qt::RightButton){QString s = QString("右键被按下\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);}else if(event->button() == Qt::MiddleButton){QString s = QString("中间键被按下\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);} } //鼠标移动重写事件函数的实现 void Widget::mouseMoveEvent(QMouseEvent *event) {ui->label->move(event->pos()); //跟着鼠标所在位置移动 } //鼠标抬起重写事件函数的实现 void Widget::mouseReleaseEvent(QMouseEvent *event) {if(event->button() == Qt::LeftButton){QString s = QString("左键被抬起\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);}else if(event->button() == Qt::RightButton){QString s = QString("右键被抬起\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);}else if(event->button() == Qt::MiddleButton){QString s = QString("中间键被抬起\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);} } //鼠标双击重写事件函数的实现 void Widget::mouseDoubleClickEvent(QMouseEvent *event) {if(event->button() == Qt::LeftButton){QString s = QString("左键被双击\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);}else if(event->button() == Qt::RightButton){QString s = QString("右键被双击\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);}else if(event->button() == Qt::MiddleButton){QString s = QString("中间键被双击\n所在位置:x:%1,y:%2").arg(event->x()).arg(event->y());ui->label->setText(s);} }
117.3 移动窗口案例
- 加到上边的源文件中
void Widget::mousePressEvent(QMouseEvent *event) {//p = event->globalPos()-this->frameGeometry().topLeft();//鼠标点击全局位置 //窗口一开始位置p=event->pos(); } void Widget::mouseMoveEvent(QMouseEvent *event) {if(event->buttons() == Qt::LeftButton){this->move(event->globalPos()-p);//鼠标点击全局位置 鼠标相对于窗口的位置} }
一百一十八、绘制事件
- 绘制事件是qt提供的二维图形引擎,能够让用户绘制各种图形,例如:适量文字、绘制图形、图像等
- 绘制事件处理函数触发情况:窗口第一次展示、窗口最小化、最大化、窗口从覆盖状态显示出来、手动拖动窗口调大小、调用update函数
- 绘制事件,依赖于画家类(QPainter)实现相关绘制工作
示例 :
- 重写的函数
//绘制事件处理函数 void Widget::paintEvent(QPaintEvent *event) { // static int num = 0; // qDebug() << ++num;//实例化一个画家QPainter p(this); //指定绘制地方//给画家设置画笔p.setPen(QColor("pink"));//给画家的笔设置字体类型p.setFont(QFont("宋体",40,10,false));p.drawText(this->rect(),Qt::AlignCenter,"好好学习,天天向上");//区域范围 }
小作业
- 写一个闹钟
我写的
clock.h
#ifndef CLOCK_H
#define CLOCK_H#include <QWidget>
#include <QTextToSpeech>
#include <QTime>
#include <QTimer>
#include <QTimeEdit>
#include <QTimerEvent>
#include <QDate>
#include <QDateTime>
#include <QPushButton>
#include <QDebug>
#include <QMouseEvent>QT_BEGIN_NAMESPACE
namespace Ui { class Clock; }
QT_END_NAMESPACEclass Clock : public QWidget
{Q_OBJECTpublic:Clock(QWidget *parent = nullptr);~Clock();void timerEvent(QTimerEvent *event) override;signals:void speak();private slots:void timeOut_solt();void speak_slot();void mousePressEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:Ui::Clock *ui;QDateTime sys_date;QTimer *sys_time,*t;int tid;QPoint p;QTextToSpeech *speecher;
};
#endif // CLOCK_H
clock.cpp
#include "clock.h"
#include "ui_clock.h"Clock::Clock(QWidget *parent): QWidget(parent), ui(new Ui::Clock)
{ui->setupUi(this);// 设置窗口为纯净模式this->setWindowFlags(Qt::FramelessWindowHint);// 直接先初始化当前时间tid = startTimer(1000);sys_time = new QTimer(this);speecher = new QTextToSpeech(this);// 初始化tt = new QTimer(this);// 连接超时信号与处理的槽函数connect(t, &QTimer::timeout, this, &Clock::timeOut_solt);
}Clock::~Clock()
{killTimer(tid);delete ui;
}void Clock::timerEvent(QTimerEvent *event)
{if(event->timerId() == tid){sys_date = QDateTime::currentDateTime();ui->nowTimeLab->setText(sys_date.toString("yyyy-MM-dd HH:mm:ss"));ui->nowTimeLab->setAlignment(Qt::AlignCenter);}
}void Clock::timeOut_solt()
{QTime the_time = QTime::currentTime();// 时间超过则直接发送语音播报信号if(the_time.toString("hh:mm:ss") >= ui->clockTimeEdit->toPlainText()){emit speak();}
}// 语音播报
void Clock::speak_slot()
{speecher->say(ui->textEdit->toPlainText());
}void Clock::mousePressEvent(QMouseEvent *event)
{p = event->pos();if(event->button() == Qt::LeftButton){// 鼠标按下位置在 关闭上if(p.x() >= ui->closeLab->x() && p.x() <= ui->closeLab->x()+ui->closeLab->width() \&& p.y() >= ui->closeLab->y() && p.y() <= ui->closeLab->y()+ui->closeLab->height()){// 按下关闭,关闭变红ui->closeLab->setStyleSheet("background-color:red");}// 鼠标按下位置在 打开上else if (p.x() >= ui->openLab->x() && p.x() <= ui->openLab->x()+ui->openLab->width() \&& p.y() >= ui->openLab->y() && p.y() <= ui->openLab->y()+ui->openLab->height()){}}
}void Clock::mouseReleaseEvent(QMouseEvent *event)
{p = event->pos();if(event->button() == Qt::LeftButton){// 鼠标松开位置在 关闭上if(p.x() >= ui->closeLab->x() && p.x() <= ui->closeLab->x()+ui->closeLab->width() \&& p.y() >= ui->closeLab->y() && p.y() <= ui->closeLab->y()+ui->closeLab->height()){// 松开关闭t->stop();ui->openLab->setStyleSheet("background-color:white");ui->openLab->setText("启动闹钟");ui->closeLab->setStyleSheet("background-color:white");disconnect(this, &Clock::speak, this, &Clock::speak_slot);}// 鼠标松开位置在 打开上else if (p.x() >= ui->openLab->x() && p.x() <= ui->openLab->x()+ui->openLab->width() \&& p.y() >= ui->openLab->y() && p.y() <= ui->openLab->y()+ui->openLab->height()){// 松开打开t->start(3000);ui->openLab->setText("已启动");ui->openLab->setStyleSheet("background-color:green");// 将语音播报信号和语音播报槽函数连接connect(this, &Clock::speak, this, &Clock::speak_slot);}}
}
main.cpp
#include "clock.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Clock w;w.show();return a.exec();
}
执行的 UI 界面
相关文章:

嵌入式养成计划-45----QT--事件机制--定时器事件--键盘事件和鼠标事件--绘制事件
一百一十五、事件机制 当这件事情发生时,会自动走对应的函数处理(重写的事件函数) 115.1 事件处理简介 什么是事件? (重点) 件是由窗口系统或者自身产生的,用以响应所发生的各类事情,比如用户按下并释放…...
git远程仓库、开发者使用流程、ssh连接
git远程仓库 https://www.cnblogs.com/liuqingzheng/p/15328319.html 远程仓库有: : github gitlab gitee 在gitee上创建了仓库 (确保仓库是空的)本地:git init本地:git commit -m 提交版本指定远程仓库地址 添加一…...

SpringBoot (3) Profiles,外部化配置,自定义starter
目录 1 Profiles 1.1 "组件"环境隔离 1.1.1 标识环境 1.1.2 激活环境 1.2 "配置"环境隔离 1.2.1 添加"副配置文件" 1.2.2 激活环境 2 外部化配置 2.1 配置优先级 2.2 快速部署 3 自定义starter 3.1 基本抽取 3.1.1 导yaml提示包 3…...

【C++】类型转换(dynamic_cast,const_cast,static_cast,reinterpret_cast)
🌏博客主页: 主页 🔖系列专栏: C ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 文章目录 C语言中的类型转换一、static_cast二、reinterpret_cast三、 const_cast四、 dynamic…...

冷笑话-1
代码检视时,程序员A看着下面的代码,疑惑地问程序员B:“为什么不用重载?” class MyClass {public MyClass queryById(long id) { //......}public MyClass queryByName(String Name) { //......}public MyClass queryByIdAndNam…...

模拟退火算法(SA)求解旅行商问题(TSP)python
目录 一、模拟退火算法求解TSP(city14)的python代码 二、city14的运行结果 三、 模拟退火算法求解TSP(city30)的python代码 四、city30的运行结果 一、模拟退火算法求解TSP(city14)的python代码 impor…...

Intelijj使用Gitee团队开发
初始化项目到Gitee服务器 成功标识: 添加团队成员 点击管理——仓库成员设置——开发者 2.添加仓库成员 (最多不超过5人) 3.通过链接或者二维码邀请新成员,或者可以自己手动添加新成员并提交 多人项目仓库创建完成 通…...

气象台使用vr模拟仿真实训教学降低成本投入
气候仿真实验室用于模拟高低温、高湿、干燥、阳光光照、降雨、降雪、覆冰、雾天与强风等多种环境适应性试验等气候和环境条件,在环境试验中,温度、湿度、光照、降雨这些常见的仿真环境都很容易实现。而比较少见的雾天、强风、降雪等环境就比较难。因此为…...

智能井盖是什么?万宾科技智能井盖传感器有什么特点
智能井盖是一种基于物联网和人工智能技术的新型城市设施。它不仅具备传统井盖的功能,还能通过数字化、自动化的方式实现远程监控和智能管理,提升城市运行效率和服务水平。 WITBEE万宾智能井盖传感器EN100-C2是一款井盖异动监测的传感终端。对窨井盖状态(…...

使用 类加载器 或者 类对象 读取文件
相对路径:项目 的 根目录 开始查找。( 但是在我们真正开发的时候,我们读到的更多的文件并不是直接放在我们项目里面这个文件夹里面,而是放在我们模块里面 )同理可得,我们直接创建 文件 b.txt 会在项目的根目…...

《深度学习推荐系统》王喆 笔记
这个笔记,是我记录的阅读该书,对我比较有用的一些点。不算是能完全覆盖全书知识点的笔记。 能完全覆盖全书知识点,比较详尽的笔记,可以参考如下。 《深度学习推荐系统》超级详细读书笔记https://www.zhihu.com/tardis/bd/art/44…...

微软Azure OpenAI支持数据微调啦!可打造专属ChatGPT
10月17日,微软在官网宣布,现在可以在Azure OpenAI公共预览版中对GPT-3.5-Turbo、Babbage-002 和Davinci-002模型进行数据微调。 使得开发人员通过自己的数据集,便能打造独一无二的ChatGPT。例如,通过海量医疗数据进行微调&#x…...

Kali Linux 安装搭建 hadoop 平台 详细教程
1)前期环境准备:(虚拟机、jdk、ssh) 2)SSH相关配置 安装SSH Server服务器:apt-get install openssh-server 更改默认的SSH密钥 cd /etc/ssh mkdir ssh_key_backup mv ssh_host_* ssh_key_backup 创建新…...
leetcode做题笔记190. 颠倒二进制位
颠倒给定的 32 位无符号整数的二进制位。 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因…...
JAVA如何获取服务器ip
一、最简单的方法就是使用InetAddress获取本机ip InetAddress.getLocalHost().getHostAddress(); public static void main(String[] args) {try {//用 getLocalHost() 方法创建的InetAddress的对象InetAddress address InetAddress.getLocalHost();System.out.println(addr…...

Power BI 傻瓜入门 4. Power BI:亮点
本章内容包含: 在Power BI Desktop上学习诀窍摄入数据使用模型试用Power BI服务 就像评估一个由多种成分组成的蛋糕一样,Power BI要求其用户熟悉商业智能(BI)解决方案中的功能。几乎所有与Power BI交互的用户都是从桌面版开始的…...
网络参考资料搬运(3)
(1) Python: 使用Python打开新的终端(terminal)并执行语句 通过Python 打开各系统(MAC, LINUX, WINDOWS)下的终端 (Terminal) python执行shell脚本的几种方法 自己写Linux命令 用Python写个Linux系统命令 Python 使用sftp传输文件…...
Bias in Emotion Recognition with ChatGPT
本文是LLM系列文章,针对《Bias in Emotion Recognition with ChatGPT》的翻译。 chatGPT在情绪识别中的偏差 摘要1 引言2 方法3 结果4 讨论5 结论 摘要 本技术报告探讨了ChatGPT从文本中识别情绪的能力,这可以作为交互式聊天机器人、数据注释和心理健康…...

【PACS系统源码】与医院HIS系统双向数据交换,实现医学影像集成与影像后处理功能
医院医学影像PACS系统源码,集成三维影像后处理功能,包括三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜、最大/小密度投影、心脏动脉钙化分析等功能。系统功能强大,代码完整。 PACS系统与医院HIS实现双向数据交换,…...
深度学习中常用的激活函数有sigmoid、tanh、ReLU、LeakyReLU、PReLU、GELU等。
深度学习中常用的激活函数 1. Sigmoid函数2. Tanh函数3. ReLU函数4. LeakyReLU函数5. PReLU函数6. ELU函数:7. GELU函数: 深度学习中常用的激活函数有sigmoid、tanh、ReLU、LeakyReLU、PReLU等。 1. Sigmoid函数 Sigmoid函数公式为 f ( x ) 1 1 e −…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...

门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
基于Uniapp的HarmonyOS 5.0体育应用开发攻略
一、技术架构设计 1.混合开发框架选型 (1)使用Uniapp 3.8版本支持ArkTS编译 (2)通过uni-harmony插件调用原生能力 (3)分层架构设计: graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...

职坐标物联网全栈开发全流程解析
物联网全栈开发涵盖从物理设备到上层应用的完整技术链路,其核心流程可归纳为四大模块:感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性,例如传感器选型需平衡精度与…...
十二、【ESP32全栈开发指南: IDF开发环境下cJSON使用】
一、JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下核心特性: 完全独立于编程语言的文本格式易于人阅读和编写易于机器解析和生成基于ECMAScript标准子集 1.1 JSON语法规则 {"name"…...

《架构即未来》笔记
思维导图 第一部分:可扩展性组织的人员配置 第二部分:构建可扩展的过程 第三部分:可扩展的架构方案 第四部分:其他的问题和挑战 资料 问软件工程研究所: https://www.sei.cmu.edu/ AKF公司博客: http://www.akfpart…...
Kafka 消息模式实战:从简单队列到流处理(一)
一、Kafka 简介 ** Kafka 是一种分布式的、基于发布 / 订阅的消息系统,由 LinkedIn 公司开发,并于 2011 年开源,后来成为 Apache 基金会的顶级项目。它最初的设计目标是处理 LinkedIn 公司的海量数据,如用户活动跟踪、消息传递和…...