嵌入式养成计划-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 −…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
