Qt事件系统 day7

Qt事件系统 day7

事件系统

  • 在Qt中,事件是派生自抽象QEvent类的对象,它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理,但它们与小部件尤其相关。
  • Qt程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始Qt的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件,当事件发生时,Qt将创建一个事件对象
  • 当事件发生时,Qt通过构造适当的QEvent子类的实例来创建一个事件对象来表示它,并通过调用它的event()函数将它交付给QObject的一个特定实例(或它的一个子类)。
  • 这个函数event()不处理事件本身;根据交付的事件类型,它为该特定类型的事件调用事件处理程序,并根据事件是被接受还是被忽略发送响应。
  • 一些事件,如QMouseEvent和QKeyEvent,来自窗口系统;还有一些,比如QTimerEvent,来自其他来源;有些来自应用程序本身。

事件处理

  • 传递事件的通常方式是调用虚函数
    在这里插入图片描述
  • 自定义处理了按钮控件左键单击,想要让父类也能够处理左键消息,可以把父类的mousePressEvent放在最后调用(不放在else中)
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
class Button :public QPushButton
{
public:Button(QWidget* parent = nullptr) :QPushButton(parent){}
protected://重写了父类的虚函数,也就是不再使用父类的实现,由自己来实现//但是按钮的点击信号,是在mousePressEvent函数里面触发的void mousePressEvent(QMouseEvent* ev) override{if (ev->button() == Qt::MouseButton::LeftButton){qDebug() << "按下小瓜";}//所以写完实现后,剩下的要交给父类处理QPushButton::mousePressEvent(ev);}
};
class Widget :public QWidget
{
public:Widget(QWidget* parent = nullptr) :QWidget(parent){auto btn = new Button(this);btn->setText("小瓜");connect(btn, &Button::clicked,this, [](){qDebug() << "小瓜瓜";});}//处理鼠标点击事件,重写虚函数即可void mousePressEvent(QMouseEvent* ev) override{//判断那个键按下if (ev->button() == Qt::MouseButton::LeftButton){//pos是程序的客户区坐标,globalPos是基于整个屏幕所在的坐标位qDebug() << "leftButton Press" << ev->pos() << ev->globalPos();}}};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

鼠标事件

  • 鼠标按下
void CustomButton::mousePressEvent(QMouseEvent* ev)override
{//获取鼠标按键 类型为枚举:Qt::MouseButton::qDebug() << ev->button();//如果同时有多个鼠标按键按下,需要判断左键是否按下qDebug() << (ev->buttons() & Qt::MouseButton::LeftButton);//获取鼠标坐标 position()返回浮点坐标,可以使用pos()获取整型坐标qDebug() << ev->position();			//鼠标在本控件上的坐标qDebug() << ev->scenePosition();		//鼠标在本控件所在的窗口位置qDebug() << ev->globalPosition();	//鼠标相对于屏幕的坐标//将其他按键传递给基类处理QPushButton::mousePressEvent(ev);
}
  • 鼠标释放
void CustomButton::mouseReleaseEvent(QMouseEvent*ev)override
{QPushButton::mouseReleaseEvent(ev);
}
  • 鼠标双击
void CustomButton::mouseDoubleClickEvent(QMouseEvent*ev)override
{qDebug() << "小瓜";
}
  • 鼠标移动
  • 如果关闭了鼠标跟踪,则只有在移动鼠标时按下鼠标按钮时才会发生鼠标移动事件。如果打开了鼠标跟踪,即使没有按下鼠标按钮,也会发生鼠标移动事件。按钮是自动追踪鼠标的,但是QWidget是不会的,如果要给QWidget的子类重写鼠标移动,需要使用 void setMouseTracking(bool enable)启用鼠标追踪。
void CustomButton::mouseMoveEvent(QMouseEvent* ev)override
{qDebug() << "鼠标移动的坐标位" << ev->pos();
}
  • 鼠标滚轮
  • 返回轮子旋转的相对量,单位为八分之一度。正值表示转轮向前旋转,远离用户;负值表示转轮向后向用户旋转。angleDelta().y()提供自上一个事件以来旋转普通垂直鼠标滚轮的角度。如果鼠标有水平滚轮,angleDelta().x()提供水平鼠标滚轮旋转的角度,否则就是0。有些鼠标允许用户倾斜滚轮来进行水平滚动,有些触摸板支持水平滚动手势;它也会出现在angleDelta().x()中。
  • 大多数鼠标类型的工作步长为15度,在这种情况下,delta值是120的倍数;即120单位* 1/8 = 15度。
  • 然而,有些鼠标的滚轮分辨率更高,发送的delta值小于120单位(小于15度)。为了支持这种可能性,可以累计添加来自事件的增量值,直到达到120的值,然后滚动小部件,或者可以部分滚动小部件以响应每个轮事件
void CustomButton::wheelEvent(QWheelEvent* ev)override
{//获取滚轮滚动方向QPoint numDegrees = ev->angleDelta();qDebug() <<"水平:" << numDegrees.x()/8 <<"垂直:" << numDegrees.y()/8;
}
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
class Button :public QPushButton
{
public:Button(QWidget* parent = nullptr) :QPushButton(parent){}
protected://重写了父类的虚函数,也就是不再使用父类的实现,由自己来实现//但是按钮的点击信号,是在mousePressEvent函数里面触发的void mousePressEvent(QMouseEvent* ev) override{if (ev->button() == Qt::MouseButton::LeftButton){qDebug() << "按下小瓜";}//所以写完实现后,剩下的要交给父类处理QPushButton::mousePressEvent(ev);}
};
class Widget :public QWidget
{
public:Widget(QWidget* parent = nullptr) :QWidget(parent){auto btn = new Button(this);btn->setText("小瓜");connect(btn, &Button::clicked,this, [](){qDebug() << "小瓜瓜";});//设置鼠标追踪,不需要的情况就不要用,会降低效率//setMouseTracking(true);}//处理鼠标点击事件,重写虚函数即可void mousePressEvent(QMouseEvent* ev) override{//判断那个键按下if (ev->button() == Qt::MouseButton::LeftButton){//pos是程序的客户区坐标,globalPos是基于整个屏幕所在的坐标位qDebug() << "leftButton Press" << ev->pos() << ev->globalPos();isPress = true;}}//鼠标放开void mouseReleaseEvent(QMouseEvent* ev) override{if (ev->button() == Qt::MouseButton::LeftButton){isPress = false;}}//移动鼠标void mouseMoveEvent(QMouseEvent* ev) override{//鼠标左键按下,并且移动了鼠标,实现这个要开启鼠标追踪if (isPress){qDebug() << "左键按下,也移动的鼠标";}//buttons判断鼠标按下后还做了别的事情if(ev->buttons() & Qt::MouseButton::RightButton){qDebug() << "移动了鼠标并且按了右击";}}//双击void mouseDoubleClickEvent(QMouseEvent* ev) override{qDebug() << "双击";}//滚轮void wheelEvent(QWheelEvent* ev) override{//判断滚轮的方向qDebug() << ev->angleDelta().y() << ev->angleDelta().x();}
private:bool isPress = false;};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

按键事件

在这里插入图片描述

在这里插入图片描述

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>class Widget :public QWidget
{
public:Widget(QWidget* parent = nullptr) :QWidget(parent){//遍历Qt中的所有快捷键for (size_t i = 0; i < 70; i++){qDebug() << i << "-----" << QKeySequence::StandardKey(i) << "------"<< QKeySequence::keyBindings(QKeySequence::StandardKey(i));}}//按键事件void keyPressEvent(QKeyEvent* ev) override{//当前是什么键按下qDebug() << Qt::Key(ev->key());//描述键 ctrl alt shift键等等//ctrl+Aif (ev->modifiers() & Qt::KeyboardModifier::ControlModifier && ev->key() == Qt::Key_A){qDebug() << "全选";}//matches:匹配if (ev->matches(QKeySequence::StandardKey::Save)){qDebug() << "保存";}}//按键放开事件void keyReleaseEvent(QKeyEvent* ev) override{}
private:
};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

窗口关闭事件、大小改变、其他事件处理

  • 窗口关闭
    • 当Qt从窗口系统接收到一个顶级小部件的窗口关闭请求时,将用给定的事件调用此事件处理程序。
    • 默认情况下,接受事件并关闭小部件。您可以重新实现此函数,以更改小部件响应窗口关闭请求的方式。例如,您可以通过在所有事件上调用ignore()来防止窗口关闭。
    • 主窗口应用程序通常使用该函数的重新实现来检查用户的工作是否已保存,并在关闭前请求权限。
void Widget::closeEvent(QCloseEvent* ev)override
{auto ret = QMessageBox::question(this, "温馨提示", "你有未保存的操作,是否保存并关闭?");if (ret == QMessageBox::StandardButton::Yes){//保存并关闭ev->accept();//ev->setAccepted(true);}else{//不保存也不关闭ev->ignore();//ev->setAccepted(false);}
}
  • 窗口隐藏、显示
    • 除隐藏和显示窗口外,窗口最小化会发送窗口隐藏事件,正常显示会发送窗口显示事件。
void Widget::showEvent(QShowEvent* ev)override
{qInfo() << "我显示啦~";
}
void Widget::hideEvent(QHideEvent* ev)override
{qInfo() << "我隐藏啦~";
}
  • 窗口移动
void Widget::moveEvent(QMoveEvent* ev)override
{qInfo() << "Widget moved" << "oldPos" << ev->oldPos() << "newPos" << ev->pos();
}
  • 窗口大小改变
void  Widget::resizeEvent(QResizeEvent* ev)override
{qInfo() << "Widget SizeChanged" << "oldSize" << ev->oldSize() << "newSize" << ev->size();
}
  • 程序状态改变
    • 如果需要检测程序中,某些东西是否发生了改变,可以通过void QWidget::changeEvent(QEvent *event)来检测。
  • 以下是常用事件
    • QEvent::FontChange
    • QEvent::WindowTitleChange
    • QEvent::IconTextChange
    • QEvent::ModifiedChange
    • QEvent::MouseTrackingChange
    • QEvent::WindowStateChange
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
class Widget :public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr) :QWidget(parent), btn(new QPushButton("更改标题", this)){resize(400, 400);btn->setFixedSize(100, 100);connect(btn, &QPushButton::clicked, this, [=](){setWindowTitle("小瓜瓜");});}//窗口关闭事件void closeEvent(QCloseEvent* ev) override{auto ret = QMessageBox::question(this, "关闭窗口", "是否保存");if (ret == QMessageBox::StandardButton::Yes){//接收事件ev->accept();}else{//忽略事件ev->ignore();}}//当窗口大小改变的时候,会调用void  resizeEvent(QResizeEvent* ev) override{//这样窗口大小改变的时候,按钮也会跟着变btn->move(ev->size().width() - btn->width(), 0);}void changeEvent(QEvent* ev) override{switch (ev->type()){case QEvent::Type::WindowTitleChange:qDebug() << "改变标题" << this->windowTitle(); break;}}
private:QPushButton* btn{};
};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

定时器

  • 有两种定时器
  • 定时器:周期性处理,因为在Qt中不能写死循环,不然会导致主程序的阻塞
  • 第一种是QTimer
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
class Widget :public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr) :QWidget(parent) {//两种定时器//1.QTimerauto timer = new QTimer(this);//最简单的调用,使用lambda表达式/*timer->callOnTimeout([](){qDebug() << "upData";});*/timer->callOnTimeout(this, &Widget::game_upData);//发送信号到槽函数connect(timer, &QTimer::timeout, this, &Widget::game_upData);//开启定时器,60帧速度timer->start(1000/60);//QTimer的静态成员,这个示例在1000毫秒后,只会触发一次QTimer::singleShot(1000, [](){qDebug() << "只触发一次";});}void game_upData(){qDebug() << __FUNCTION__;}
private:};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述
  • 第二种定时器事件,只要在QOBject的子类里面,就可以重写定时器事件
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
class Widget :public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr) :QWidget(parent){//开启定时器timer_idOne = startTimer(500);timer_idTow = startTimer(200);}//定时器事件void timerEvent(QTimerEvent* ev) override{static int i = 0;//当i为6的时候杀死定时器if (i == 6){killTimer(timer_idOne);killTimer(timer_idTow);//killTimer(ev->timerId());}if (ev->timerId() == timer_idOne){qDebug() << timer_idOne;}else if (ev->timerId() == timer_idTow){qDebug() << timer_idTow;}i++;}private://timer的id接收变量int timer_idOne;int timer_idTow;
};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

自定义事件的发送与处理

事件分发函数

  • 传递事件通常方式是调用虚函数,如果在虚函实现中不执行必要的工作,则可能需要调用基类的实现
  • 如果希望替换基类的事件处理函数,则必须自己实现所有的内容,实现自己所需的功能后,可以调用基类来获得不想处理的任何情况的默认行为
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
class Widget :public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr) :QWidget(parent){}//所有的事件处理函数都是从event()事件派发函数调用的bool event(QEvent* ev) override{switch (ev->type()){//实现自己需要的事件操作case QEvent::MouseButtonPress:mousePressEvent(dynamic_cast<QMouseEvent*>(ev)); break;default:break;}//最后交给父类去处理return QWidget::event(ev);}void mousePressEvent(QMouseEvent* ev) override{qDebug() << ev->button();}
private:};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述
发送事件
  • 自定义事件创建与发送,通过构造合适的事件对象并进行使用
  • sendEvent():立即处理事件。当它返回时,事件过滤器或对象本身已经处理了该事件,对于许多事件类。都有一个名为isAccept()的函数,它会告诉事件是被最后一个调用的处理程序接受还是拒绝
  • postEvent():将事件发送到队列中,以便进行分派。它会分发所有发布的事件。
  • 用户自定义的类型必须要在这个区间里
    在这里插入图片描述
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
//自定义事件
class CustomEvent :public QEvent
{
public:enum Type { custom = QEvent::User };CustomEvent(const QString& data) :QEvent(static_cast<QEvent::Type>(custom)),m_data(data){}//析构函数~CustomEvent(){qDebug() << __FUNCTION__;}//提供接口QString data() const{return m_data;}
protected:QString m_data;
};
class Widget :public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr) :QWidget(parent){}void mousePressEvent(QMouseEvent* ev) override{if (ev->button() == Qt::RightButton){//向指定的对象发送事件//1.sendEvent 发送栈区的事件,直到事件处理或完成之后,才会返回(表明sendEvent函数是阻塞的)//如果申请内存放在堆区就不会自动释放,需要自己所手动释放//CustomEvent ev("小瓜 sendEvetn customEvent");//QApplication::sendEvent(this, &ev);//2.postEvent 只能发送堆区的对象。一旦发送,直接返回,不需要等事件处理完成,一旦事件处理完成会自动释放CustomEvent* ev = new CustomEvent("小瓜瓜");QApplication::postEvent(this, ev);}}//处理自定义事件函数void customEvent(QEvent* ev) override{if (ev->type() == CustomEvent::custom){auto cev = dynamic_cast<CustomEvent*>(ev);if (cev){qDebug() <<  cev->data();}}}
private:
};int main(int argc, char* argv[])
{QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));w.show();return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue绑定style和class 对象写法

适用于&#xff1a;要绑定多个样式&#xff0c;个数确定&#xff0c;名字也确定&#xff0c;但不确定用不用。 绑定 class 样式【对象写法】&#xff1a; .box{width: 100px;height: 100px; } .aqua{background-color: aqua; } .border{border: 20px solid red; } .radius{bor…

真人现在猫鼠躲猫猫游戏搭建流程:专业思考与深度思考

真人现在猫鼠躲猫猫游戏是种充满乐趣和挑战的团队竞技游戏。本文将从游戏规则设计、场地布置、技术实现和用户体验等方面&#xff0c;深入探讨人现在猫鼠躲猫猫游戏的搭建流程&#xff0c;并结合专业思考与深度思考&#xff0c;为游戏搭建提供全面指导。 一、游戏规则设计&…

小程序uView2.X框架upload组件上传方法总结+避坑

呈现效果: 1.1单图片上传 1.2多图片上传 前言:相信很多人写小程序会用到uView框架,总体感觉还算OK吧,只能这么说,肯定也会遇到图片视频上传,如果用到这个upload组件相信你,肯定遇到各种各样的问题,这是我个人总结的单图片和多图片上传方法. uView2.X框架:uView 2.0 - 全面兼容…

适用于音视频的弱网测试整理

一、什么是弱网环境 对于弱网的定义&#xff0c;不同的应用对弱网的定义是有一定的差别的&#xff0c;不仅要考虑各类型网络最低速率&#xff0c;还要结合业务场景和应用类型去划分。按照移动的特性来说&#xff0c;一般应用低于2G速率的都属于弱网&#xff0c;也可以将3G划分…

idea自动封装方法

例如 package com.utils;import java.lang.reflect.Field; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle;/*** author hrui* date 2023/10/13 13:49*/ public class DBUtils {private static ResourceBundle bund…

【Pytorch】pytorch中保存模型的三种方式

【Pytorch】pytorch中保存模型的三种方式 文章目录 【Pytorch】pytorch中保存模型的三种方式1. torch保存模型相关的api1.1 torch.save()1.2 torch.load()1.3 torch.nn.Module.load_state_dict()1.4 什么是state_dict()1.4. 1 举个例子 2. pytorch模型文件后缀3. 存储整个模型3…

Netty深入浅出Java网络编程学习笔记(二) Netty进阶应用篇

目录 四、应用 1、粘包与半包 现象分析 粘包 半包 本质 解决方案 短链接 定长解码器 行解码器 长度字段解码器——LTC 2、协议设计与解析 协议的作用 Redis协议 HTTP协议 自定义协议 组成要素 编码器与解码器 编写测试类 Sharable注解 自定义编解码器能否使用Sharable注解 3、在…

科技为饮食带来创新,看AI如何打造智能营养时代

在当今社会&#xff0c;快节奏的生活方式、便捷的食品选择以及现代科技的快速发展正深刻地重塑着我们对健康的认知和实践&#xff0c;它已经不再仅仅是一个话题&#xff0c;而是一个备受关注的社会焦点。在这个纷繁复杂的交汇点上&#xff0c;AI技术的介入为我们开辟了前所未有…

【Rust笔记】浅聊 Rust 程序内存布局

浅聊Rust程序内存布局 内存布局看似是底层和距离应用程序开发比较遥远的概念集合&#xff0c;但其对前端应用的功能实现颇具现实意义。从WASM业务模块至Nodejs N-API插件&#xff0c;无处不涉及到FFI跨语言互操作。甚至&#xff0c;做个文本数据的字符集转换也得FFI调用操作系统…

云原生网关可观测性综合实践

作者&#xff1a;钰诚 可观测性 可观测性&#xff08;Observability&#xff09;是指系统、应用程序或服务的运行状态、性能和行为能够被有效地监测、理解和调试的能力。 随着系统架构从单体架构到集群架构再到微服务架构的演进&#xff0c;业务越来越庞大&#xff0c;也越来…

QMidi Pro for Mac:打造您的专属卡拉OK体验

你是否曾经厌倦于在KTV里与朋友们争夺麦克风&#xff1f;是否想要在家中享受自定义的卡拉OK体验&#xff1f;现在&#xff0c;有了QMidi Pro for Mac&#xff0c;一切变得简单而愉快&#xff01; QMidi Pro是一款功能强大的卡拉OK播放器&#xff0c;专为Mac用户设计。它充分利…

【C语言】程序环境和预处理

程序环境&#xff1a; 1、C语言的任何一种实现&#xff0c;存在两个不同的环境&#xff1b; 2、翻译环境&#xff1a;将源代码转换成可执行的二进制指令&#xff08;机器指令&#xff09;&#xff1b;.c文件&#xff08;源文件——文本信息的代码&#xff09;->&#xff0…

论文学习——Class-Conditioned Latent Diffusion Model For DCASE 2023

文章目录 引言正文AbstractIntroductionSystem Overview2.1 Latent Diffusion with sound-class-based conditioning以声音类别为条件的潜在扩散模型2.2 Variational Autoencoder and neural vocoder变分自编码器和神经声码器FAD-oriented Postprocessing filter&#xff08;专…

Linux开启SSH

Linux开启SSH 1.虚拟机确定连通性 如果是虚拟机的话则需要进行确定和宿主主机之间能正常联通(不能联通还远程个啥) 获取到虚拟机的IP 参考文章:Linux获取本机IP地址使用宿主机ping一下虚拟机的IP查看是否联通 2.安装SSH服务端 安装工具来使得能够通过SSH进行连接 命令 sudo a…

springBoot组件注册

springBoot组件注册 前言1、创建组件文件2、写属性3、生成get和set方法4、以前注册的方法5、现在注册的方法6、在启动文件查看7、多实例Scope("prototype")8、注册第三方包导入对应的场景启动器注册组件查看是否存在也可以通过Import(FastsqlException.class)导入但是…

C++医院影像科PACS源码:三维重建、检查预约、胶片打印、图像处理、测量分析等

PACS连接DICOM接口的医疗器械&#xff08;如CT、MRI、CR、DR、DSA、各种窥镜成像系统设备等&#xff09;&#xff0c;实现图像无损传输&#xff0c;实现DICOM胶片打印机回传打印功能&#xff0c;支持各种图像处理&#xff0c;可以进行窗技术调节&#xff0c;与登记台管理系统共…

Spring Boot 中的 TransactionTemplate 是什么,如何使用

Spring Boot中的TransactionTemplate&#xff1a;简化事务管理 事务管理是任何应用程序中至关重要的部分&#xff0c;特别是在处理数据库操作时。Spring Boot提供了多种方式来管理事务&#xff0c;其中之一是使用TransactionTemplate。本文将深入探讨TransactionTemplate是什么…

树莓派玩转openwrt软路由:5.OpenWrt防火墙配置及SSH连接

1、SSH配置 打开System -> Administration&#xff0c;打开SSH Access将Interface配置成unspecified。 如果选中其他的接口表示仅在给定接口上侦听&#xff0c;如果未指定&#xff0c;则在所有接口上侦听。在未指定下&#xff0c;所有的接口均可通过SSH访问认证。 2、防火…

如何在手机上设置节日提醒和倒计时天数?

在平淡的生活和工作中&#xff0c;时不时有各种各样节日的点缀&#xff0c;为我们的日常增添了一些仪式感&#xff0c;例如春节、元宵节、情人节、端午节、七夕节等。此外还有一些特殊的日子也值得纪念&#xff0c;例如恋爱纪念日、结婚纪念日、亲朋好友生日等。面对这些节日&a…

CodeForces每日好题10.14

给你一个字符串 让你删除一些字符让它变成一个相邻的字母不相同的字符串&#xff0c;问你最小的删除次数 以及你可以完成的所有方/案数 求方案数往DP 或者 组合数学推公式上面去想&#xff0c;发现一个有意思的事情 例如1001011110 这个字符串你划分成1 00 1 0 1111 0 每…