QT 学习笔记(九)

news/2024/5/4 4:28:49/文章来源:https://blog.csdn.net/weixin_45891612/article/details/128203581

文章目录

  • 一、事件的接收和忽略
    • 1. 准备工作
    • 2. 接收和忽略
  • 二、event() 函数
    • 1. 简介
    • 2. 实例演示
    • 3. 总结
  • 三、事件过滤器
  • 四、总结(细看)
    • 1. 知识点汇总
    • 2. QT 的事件处理
  • 五、事件、事件的接收和忽略、event() 函数和事件过滤器代码
    • 1. 主窗口头文件 mywidget.h
    • 2. 主窗口源文件 mywidget.cpp
    • 3. 标签头文件 mylabel.h
    • 4. 标签源文件 mylabel.cpp
    • 5. 按钮头文件 mybutton.h
    • 6. 按钮源文件 mybutton.cpp

由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。
提示:具体项目创建流程和注意事项见QT 学习笔记(一)
提示:具体项目准备工作和细节讲解见QT 学习笔记(二)

一、事件的接收和忽略

  • 在上文的代码基础上继续进行操作。QT 学习笔记(八)

1. 准备工作

  • 在 ui 界面新建一个按钮,在项目文件当中新建一个 mybutton 的 C++ 类。
  • 将 ui 界面的按钮提升为 mybutton 。自定义控件提升详见QT 学习笔记(七)。
  • 在 主窗口源文件 mywidget.cpp 当中对按钮进行操作,对基本功能进行测验。
  • 注意:要在项目文件 day8.pro 当中添加 CONFIG +=C++11 才可以使 connect 功能正常实现。
    在这里插入图片描述
  • 当我们点击按钮时,会在输出窗口输出按钮被按下,如下图所示:
    在这里插入图片描述

2. 接收和忽略

  • 在上一步的检测操作完成后,在按钮源文件 mybutton.cpp 当中,进行事件的接收和忽略操作。
  • 通过 if 语句,对鼠标左键按下在输出窗口输出按下的是左键,对其他鼠标按键不做处理,调用原函数。
  • 在上述操作当中,鼠标左键对应的就是事件的接收其他按键对应的就是事件的忽略
    在这里插入图片描述
  • 在这里有一个问题,当我们按下鼠标左键时,会输出按下的是左键,但当我们按下其他按键时,并没有调用原函数,即输出按钮被按下。
  • 这是因为当我们按下鼠标左键的时候,事件的信号被 qDebug() 输出语句给拦截了,不会再向后传递,无法走到 else 对应的内容。
  • 因此,在我们编写代码时,事件的忽略不要编写实现代码即可
  • 事件的接收,就不会往下传递。
  • 事件的忽略,事件会继续往下传递。
  • 我们可以把 QT 的事件传递看成链状:如果子类没有处理这个事件,就会继续向其父组件传递。
  • QT 的事件对象有两个函数:accept() 和 ignore() 。
  • accept() 用来告诉 QT,这个类的事件处理函数想要处理这个事件;
  • 如果一个事件处理函数调用了一个事件对象的 accept() 函数,这个事件就不会被继续传播给其父组件。
  • ignore() 用来告诉 QT,这个类的事件处理函数不想要处理这个事件;
  • 如果调用了事件的 ignore() 函数,QT 会从其父组件中寻找另外的接受者。在事件处理函数中,可以使 isAccepted() 来查询这个事件是不是已经被接收了。
  • 我们在主窗口 myWidget.cpp 中,重写鼠标点击事件,每当鼠标按下的时候,输出 ++++++++++,同时,将按钮窗口 mybutton.cpp 当中的 e->ignore() 注释掉,得到如下现象:
    在这里插入图片描述
  • 这样操作并不会输出 ++++++++++。此时,我们取消按钮窗口 mybutton.cpp 当中的 e->ignore() 的注释,得到下面的现象:
    在这里插入图片描述
  • 当我们点击按钮的时候,会同时输出按下的是左键和 ++++++++++,当我们点击按钮外的界面时,只会输出 ++++++++++。
  • 这是因为没有接收到信号,所以没有触发那里的 e->ignore()。而这里的 e->ignore() 可以让这个信号再次传递下去,不过不是传递给 mybutton,而是 父组件 mywidget。
  • 这个 e->ignore() 主要使用在关闭项目当中,也就是窗口右上角大家熟知的红色关闭按钮,在此简单实现一下(只展示实现现象,具体代码会在总体代码当中展示)。
  • 在我们实际关闭窗口的时候,往往会弹出一句 确定关闭吗? 这种类似的提示。
  • 为了实现这样的功能,需要包含头文件 QMessageBox ,使用 question() 函数。question() 函数中的第一个参数是指定父对象,第二个参数是标题,第三个参数是提示内容,第四个参数不写的话默认有两个按钮:yes 和 no 。
  • 为实现功能,只需要一个简单 if 语句即可,如果点击 yes ,则处理关闭窗口事件,接收事件,事件就不会再往下传递;如果点击 no ,则忽略事件,事件继续给父组件传递。
  • 具体现象如下图所示:
    在这里插入图片描述

二、event() 函数

1. 简介

  • 事件对象创建完毕后,QT 将这个事件对象传递给 QObject 的 event() 函数。event() 函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理器(event handler)。
  • 因此,event() 函数主要用于 事件的分发。所以,如果你希望在事件分发之前做一些操作,就可以重写这个 event() 函数了。
  • 例如,我们希望在一个 QWidget 组件中监听 tab 键的按下,那么就可以继承 QWidget,并重写它的 event() 函数,来达到这个目的。
  • 事件分发如下图所示。
    在这里插入图片描述
  • 与其他的事件返回值不同的是,event() 事件的返回值是 bool 类型。
  • 如果传入的事件已被识别并且处理,则需要返回 true,否则返回 false。如果返回值是 true,那么 QT 会认为这个事件已经处理完毕,不会再将这个事件发送给其它对象, 而是会继续处理事件队列中的下一事件。
  • 在 event() 函数中,调用事件对象的 accept() 和 ignore() 函数是没有作用的,不会影响到事件的传播。
  • 相当于在所有信号接收前进行一个检查,满足要求的停止工作,其他的继续原动作。

2. 实例演示

  • 在此以定时器为例,重写 event() 函数,使得定时器停止工作,其他部件保持原动作。代码和实现结果如下:
//重写event事件
bool myWidget::event(QEvent *e)
{if(e->type()==QEvent::Timer){//干掉定时器//如果返回true,事件停止传播return true;}else{return QWidget::event(e);}
}

在这里插入图片描述

  • 将其恢复正常需要一个强制类型转换,只需在上述代码当中添加如下代码即可:
QTimerEvent *env = static_cast<QTimerEvent *>(e);timerEvent(env);
  • 正常现象如下图所示:

在这里插入图片描述

  • 我们在此继续进行一个按键 B 的 event() 函数重写,只有当我们按下按键 B 的时候,事件才继续,其他的事件均终止。代码和实现结果如下:
else if(e->type()==QEvent::KeyPress){//类型转换QKeyEvent *env = static_cast<QKeyEvent *>(e);if(env->key()==Qt::Key_B){return QWidget::event(e);}return true;}

在这里插入图片描述

3. 总结

  • QTimerEvent() 和 QKeyEvent() 这样的函数,就是前面所说的事件处理器 event handler。
  • event() 函数中实际是通过事件处理器来响应一个具体的事件。这相当于 event() 函数将具体事件的处理“委托”给具体的事件处理器。而这些事件处理器是 protected virtual 的,因此,我们重写了某一个事件处理器,即可让 QT 调用我们自己实现的版本。
  • event() 是一个集中处理不同类型的事件的地方。如果你想重写一大堆事件处理器,就可以重写这个 event() 函数,通过 QEvent::type() 判断不同的事件。由于重写 event() 函数需要十分小心注意父类的同名函数的调用,一不留神就可能出现问题。
  • 因此,一般只重写事件处理器(当然,也必须记得是不是应该调用父类的同名处理器)。这其实也表明了 event() 函数的另外一个作用:屏蔽掉某些不需要的事件处理器

三、事件过滤器

  • 很多时候,对象需要查看、甚至要拦截发送到另外对象的事件。例如,对话框可能想要拦截按键事件,不让别的组件接收到;或者要修改回车键的默认处理。
  • 通过前文,我们已经知道,QT 创建了 QEvent 事件对象之后,会调用 QObject 的 event() 函数处理事件的分发。显然,可以在 event() 函数中实现拦截的操作。由于 event() 函数是 protected 的,因此,需要继承已有类。如果组件很多,就需要重写很多个 event() 函数。这当然相当麻烦,更不用说重写 event() 函数还得小心一堆问题。
  • 因此,我们采用 QT 提供的另外一种机制来达到这一目的:事件过滤器。

在这里插入图片描述

  • QObject 有一个 eventFilter() 函数,用于建立事件过滤器。函数原型如下:
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );
  • 事件过滤器,可以理解成一种过滤代码。事件过滤器会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。这个函数返回一个 bool 类型,如果你想将参数 event 过滤出来,比如,不想让它继续转发,就返回 true,否则返回 false。
  • 事件过滤器的调用时间是目标对象(也就是参数里面的 watched 对象)接收到事件对象之前。也就是说,如果你在事件过滤器中停止了某个事件,那么,watched 对象以及以后所有的事件过滤器根本不会知道这么一个事件。
  • 在实现事件过滤器之前,我们要在 ui 界面选取一个合适的标签,在这里选择的是 label_2 。 在选择完成后进行操作安装过滤器,该函数的参数是由哪个函数的父对象进行处理。
//安装过滤器
ui->label_2->installEventFilter(this);
  • 通过事件过滤器,将 label_2 ,转换为鼠标移动,并实时显示出对应的 x 和 y 坐标,其他事件保持不变。(鼠标按下和释放的整体流程与鼠标移动是相同的,按钮的操作方法和标签也是相同的,具体代码在汇总时展示)

在这里插入图片描述

  • 注意:事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。

四、总结(细看)

1. 知识点汇总

  • QT 的事件是整个 QT 框架的核心机制之一。涉及到的函数众多,而处理方法也很多。
  • QT 中有很多种事件:鼠标事件、键盘事件、大小改变的事件、位置移动的事件等等。如何处理这些事件,实际有两种选择:
  • (1) 所有事件对应一个事件处理函数,在这个事件处理函数中用一个很大的分支语句进行选择。
  • (2) 每一种事件对应一个事件处理函数。QT 就是使用的这么一种机制:mouseEvent() ,keyPressEvent() 等。
  • QT 具有这么多种事件处理函数,肯定有一个地方对其进行分发,否则,QT 怎么知道哪一种事件调用哪一个事件处理函数呢?这个分发的函数,就是 event()。显然,当 QMouseEvent 产生之后, event() 函数将其分发给 mouseEvent() 事件处理器进行处理。
  • event() 函数会有两个问题:
  • (1) event() 函数是一个 protected 的函数,这意味着我们要想重写 event() ,必须继承一个已有的类。试想,我的程序根本不想要鼠标事件,程序中所有组件都不允许处理鼠标事件,是不是我得继承所有组件,一 一重写其 event() 函数?protected 函数带来的另外一个问题是,如果我基于第三方库进行开发,而对方没有提供源代码,只有一个链接库,其它都是封装好的。我怎么去继承这种库中的组件呢?
  • (2) event() 函数的确有一定的控制,不过有时候需求更严格一些:我希望那些组件根本看不到这种事件。event() 函数虽然可以拦截,但其实也是接收到了 QMouseEvent 对象。我连让它收都收不到。这样做的好处是,模拟一种系统根本没有那个事件的效果,所以其它组件根本不会收到这个事件,也就无需修改自己的事件处理函数。
  • 这两个问题是 event() 函数无法处理的。于是,QT 提供了另外一种解决方案:事件过滤器。事件过滤器给我们一种能力,让我们能够完全移除某种事件。事件过滤器可以安装到任意 QObject 类型上面,并且可以安装多个。如果要实现全局的事件过滤器,则可以安装到 QApplication 或者 QCoreApplication 上面。这里需要注意的是,如果使用 installEventFilter() 函数给一个对象安装事件过滤器,那么该事件过滤器只对该对象有效,只有这个对象的事件需要先传递给事件过滤器的 eventFilter() 函数进行过滤,其它对象不受影响。如果给 QApplication 对象安装事件过滤器,那么该过滤器对程序中的每一个对象都有效,任何对象的事件都是先传给 eventFilter() 函数。
  • 事件过滤器可以解决刚刚我们提出的 event() 函数的两点不足:
  • (1) 事件过滤器不是 protected 的,因此我们可以向任何 QObject 子类安装事件过滤器;
  • (2) 事件过滤器在目标对象接收到事件之前进行处理,如果我们将事件过滤掉,目标对象根本不会见到这个事件。

2. QT 的事件处理

  • QT 的事件处理,实际上是有五个层次:
  • (1) 重写 paintEvent() 、mousePressEvent() 等事件处理函数。这是最普通、最简单的形式,同时功能也最简单。
  • (2) 重写 event() 函数。event() 函数是所有对象的事件入口,QObject 和 QWidget 中的实现,默认是把事件传递给特定的事件处理函数。
  • (3) 在特定对象上面安装事件过滤器。该过滤器仅过滤该对象接收到的事件。
  • (4) 在 QCoreApplication::instance() 上面安装事件过滤器。该过滤器将过滤所有对象的所有事件,因此和 notify() 函数一样强大,但是它更灵活,因为可以安装多个过滤器。全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件。全局过滤器有一个问题:只能用在主线程。
  • (5) 重写 QCoreApplication::notify() 函数。这是最强大的,和全局事件过滤器一样提供完全控制,并且不受线程的限制。但是全局范围内只能有一个被使用(因为 QCoreApplication 是单例的)。

五、事件、事件的接收和忽略、event() 函数和事件过滤器代码

1. 主窗口头文件 mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H#include <QWidget>namespace Ui {
class myWidget;
}class myWidget : public QWidget
{Q_OBJECTpublic:explicit myWidget(QWidget *parent = nullptr);~myWidget();protected://键盘按下事件void keyPressEvent(QKeyEvent *);//计时器事件void timerEvent(QTimerEvent *);//重写鼠标点击事件void mousePressEvent(QMouseEvent *);//关闭事件void closeEvent(QCloseEvent *);//重写event事件bool event(QEvent *);//事件过滤器bool eventFilter(QObject *,QEvent *);private:Ui::myWidget *ui;int timeid;int timeid2;
};#endif // MYWIDGET_H

2. 主窗口源文件 mywidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>
#include <QKeyEvent>
#include <QCloseEvent>
#include <QMessageBox>
#include <QEvent>myWidget::myWidget(QWidget *parent) :QWidget(parent),ui(new Ui::myWidget)
{ui->setupUi(this);//启动计时器timeid = this->startTimer(1000);  //毫秒为单位。每隔1s触发一次定时器timeid2 = this->startTimer(500);  //毫秒为单位。每隔0.5s触发一次定时器connect(ui->pushButton,&mybutton::clicked,[=](){qDebug()<<"按钮被按下";});//安装过滤器ui->label_2->installEventFilter(this);//设置鼠标追踪ui->label_2->setMouseTracking(tr);
}myWidget::~myWidget()
{delete ui;
}//键盘按下事件
void myWidget::keyPressEvent(QKeyEvent *e)
{qDebug()<<(char)e->key();if(e->key()==Qt::Key_A){qDebug()<<"Qt::Key_A";}
}//计时器事件
void myWidget::timerEvent(QTimerEvent *e)
{if(e->timerId()==this->timeid){static int sec = 0;ui->label->setText(QString("<center><h1>time out:%1</h1></center>").arg(sec++));//停止计时器/*if(5==sec){this->killTimer(this->timeid);}    */}else if (e->timerId()==this->timeid2){static int sec = 0;ui->label_2->setText(QString("<center><h1>time out:%1</h1></center>").arg(sec++));//停止计时器/*if(5==sec){this->killTimer(this->timeid);}    */}
}//重写鼠标点击事件
void myWidget::mousePressEvent(QMouseEvent *e)
{qDebug()<<"++++++++++";
}//重写鼠标点击事件
void myWidget::closeEvent(QCloseEvent *e)
{int ret = QMessageBox::question(this,"question","是否需要关闭窗口");//question 第一个参数是指定父对象,第二个参数是标题,//第三个参数是提示内容,第四个参数不写的话默认有两个按钮:yes和no。if(ret==QMessageBox::Yes){//关闭窗口//处理关闭窗口事件,接收事件,事件就不会再往下传递e->accept();}else{//不关闭窗口//忽略事件,事件继续给父组件传递e->ignore();}
}//重写event事件
bool myWidget::event(QEvent *e)
{if(e->type()==QEvent::Timer){//干掉定时器//如果返回true,事件停止传播//QTimerEvent *e//QTimerEvent *env = static_cast<QTimerEvent *>(e);//timerEvent(env);return true;}else if(e->type()==QEvent::KeyPress){//类型转换QKeyEvent *env = static_cast<QKeyEvent *>(e);if(env->key()==Qt::Key_B){return QWidget::event(e);}return true;}else{return QWidget::event(e);}
}//事件过滤器
bool myWidget::eventFilter(QObject *obj,QEvent *e)
{if(obj==ui->label_2){//类型转换QMouseEvent *env=static_cast<QMouseEvent *>(e);//判断事件if(e->type()==QEvent::MouseMove){ui->label_2->setText(QString("mouse move:(%1,%2)").arg(env->x()).arg(env->y()));return true;}else{return QWidget::eventFilter(obj,e);}}else{return QWidget::eventFilter(obj,e);}
}

3. 标签头文件 mylabel.h

#ifndef MYLABEL_H
#define MYLABEL_H#include <QLabel>class mylabel : public QLabel
{Q_OBJECT
public:explicit mylabel(QWidget *parent = nullptr);protected://鼠标点击事件void mousePressEvent(QMouseEvent *ev);//鼠标释放事件void mouseReleaseEvent(QMouseEvent *ev);//鼠标移动事件void mouseMoveEvent(QMouseEvent *ev);//进入窗口区域void enterEvent(QEvent *);//离开窗口区域void leaveEvent(QEvent *);signals:public slots:
};#endif // MYLABEL_H

4. 标签源文件 mylabel.cpp

#include "mylabel.h"
#include <QMouseEvent>mylabel::mylabel(QWidget *parent) : QLabel(parent)
{}//鼠标点击事件
void mylabel::mousePressEvent(QMouseEvent *ev)
{int i=ev->x();int j=ev->y();//sprinf 字符串格式化命令/** QString str = QString("abc %1 ^_^ %2").arg(123).arg("mike");* str = abc 123 ^_^ mike*/QString text = QString("<center><h1>mouse press:(%1,%2)</h1></center>").arg(i).arg(j);// center 居中,h1 一级标题this->setText(text);
}//鼠标释放事件
void mylabel::mouseReleaseEvent(QMouseEvent *ev)
{QString text = QString("<center><h1>mouse release:(%1,%2)</h1></center>").arg(ev->x()).arg(ev->y());this->setText(text);
}//鼠标移动事件
void mylabel::mouseMoveEvent(QMouseEvent *ev)
{QString text = QString("<center><h1>mouse move:(%1,%2)</h1></center>").arg(ev->x()).arg(ev->y());//this->setText(text);
}//进入窗口区域
void mylabel::enterEvent(QEvent *e)
{QString text = QString("<center><h1>mouse enter</h1></center>");this->setText(text);
}//离开窗口区域
void mylabel::leaveEvent(QEvent *e)
{QString text = QString("<center><h1>mouse leave</h1></center>");this->setText(text);
}

5. 按钮头文件 mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H#include <QPushButton>class mybutton : public QPushButton
{Q_OBJECT
public:explicit mybutton(QWidget *parent = nullptr);protected:void mousePressEvent(QMouseEvent *e);signals:public slots:
};#endif // MYBUTTON_H

6. 按钮源文件 mybutton.cpp

#include "mybutton.h"
#include <QMouseEvent>
#include <QDebug>mybutton::mybutton(QWidget *parent) : QPushButton(parent)
{}void mybutton::mousePressEvent(QMouseEvent *e)
{if(e->button() == Qt::LeftButton){//如果是左键按下qDebug()<<"按下的是左键";//事件接收后,就会往下传递e->ignore();//忽略,事件继续往下传递,事件传递给了父组件,不是给父类(基类)}else{//不做处理QPushButton::mousePressEvent(e);//事件的忽略,事件继续往下传递}
}

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

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

相关文章

音视频面试涨知识(四)

视频格式播放体验流量占用情况DASH统计直播推流端到播放端延时。支持和视频帧绑定的内容交互。比如&#xff0c;直播答题在播放端的弹窗等。小HLS对视频进行切片&#xff0c;按切片播放&#xff0c;缓存小起播快&#xff1b;拖动时间轴到任意时间播放时&#xff0c;可以快速定位…

【爬虫】JS调试解决反爬问题系列1

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

面向切面编程 AOP

AOPAOP的概念AOP &#xff08;底层原理&#xff09;AOP 底层使用动态代理AOP &#xff08; JDK 动态代理&#xff09;首先我们来看一下 Spring 的百度百科   Spring 框架是一个开放源代码的 J2EE 应用程序框架&#xff0c;由 Rod Johnson 发起&#xff0c;是针对 Bean 的生命…

《Linux运维总结:基于xtrabackup8工具全量物理备份Mysql8数据自动化工具(方案一)》

一、背景信息 说明&#xff1a;由于业务系统的特殊性&#xff0c;对数据的备份要求非常高&#xff0c;且数据量非常大&#xff0c;所以这里采用xtrabackup工具来对Mysql数据库进行全量物理备份。由于xtrabackup工具操作复杂&#xff0c;这里为了简便&#xff0c;基于xtrabackup…

这可能是2022最全的Java面试八股文!共计1658页,Java技术手册的天花板

前两天有个小伙伴在后台留言&#xff0c;最近的面试越来越难了&#xff0c;尤其是技术面&#xff0c;考察得越来越细&#xff0c;越来越底层&#xff0c;庆幸的是最终顺利找到了工作。 一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识 比如果这样的问题…

首次曝光,Alibaba大佬手撸堪称神级的SpringSecurity全彩手册

有人调侃我们说&#xff1a; 程序员不如送外卖。送外卖是搬运食物&#xff0c;自己是搬运代码&#xff0c;都不产出新的东西……透支体力&#xff0c;又消耗健康&#xff0c;可替代性极强&#xff0c;30岁之后就要面临被优化的危险……想跳槽&#xff0c;但是更高的平台难进&a…

MySQL的基础架构简述

文章目录一、一条SQL查询语句是如何执行的1、连接器2、查询缓存3、分析器4、优化器5、执行器一、一条SQL查询语句是如何执行的 开篇先上基本架构示意图&#x1f917;&#xff1a; 大体来说&#xff0c;MySQL可以分为 Server 层和存储引擎两部分。 Server 层包括连接…

重磅!阿里巴巴三入Java 全球管理组织执行委员会 龙蜥拥抱上游开源生态

近日&#xff0c;Java 全球管理组织 Java Community Process&#xff08;以下简称 JCP&#xff09;经过公平公正的投票&#xff0c;披露了入选最高执行委员会的成员名单&#xff0c;阿里巴巴作为唯一中国代表实现第三次连任。作为龙蜥社区理事长单位&#xff0c;阿里巴巴的此次…

【DevOps实战系列】第八章:详解Jenkins集成Docker私服Nexus3

个人亲自录制全套DevOps系列实战教程 &#xff1a;手把手教你玩转DevOps全栈技术 Jenkins集成Docker镜像仓库 docker私服已经搭建完毕&#xff0c;下边我们期望jenkins做的事是&#xff1a; ①通过git拉取代码②通过maven构建生成jar包③构建含有jar包的镜像④推送到docker仓库…

Halcon图像拼接

图像拼接在实际的应用场景很广&#xff0c;比如无人机航拍&#xff0c;遥感图像等等&#xff0c;图像拼接是进一步做图像理解基础步骤&#xff0c;拼接效果的好坏直接影响接下来的工作&#xff0c;所以一个好的图像拼接算法非常重要。 如按下图是将两张楼房图片拼接成一个图像。…

微服务框架 SpringCloud微服务架构 多级缓存 46 JVM 进程缓存 46.1 导入商品案例【MySQL环境准备】

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存46 JVM 进程缓存46.1 导入商品案例【MySQL环境准备】46.1.1 导入商品管理案例46 JVM 进程缓存 用于在T…

Jmeter(十七):利用jmeter插件收集性能测试结果汇总报告和聚合报告,利用PerfMon插件收集监控服务器资源指标

利用jmeter插件收集性能测试结果 汇总报告&#xff08;Summary Report &#xff09; 用来收集性能测试过程中的请求以及事务各项指标。通过监听器--汇总报告 可以添加该元件。界面如下图所示 汇总报告界面介绍&#xff1a; 所有数据写入一个文件&#xff1a;保存测试结果到本地…

STM32F4 | 定时器中断实验

文章目录一、STM32F429 通用定时器简介二、硬件设计三、软件设计四、实验现象五、STM32CubeMX 配置定时器更新中断功能这一章介绍如何使用 STM32F429 的通用定时器&#xff0c; STM32F429 的定时器功能十分强大&#xff0c;有 TIME1 和 TIME8 等高级定时器&#xff0c;也有 …

零钱通项目(面向过程)

目录 项目需求 项目界面 思路 写代码 第一步 第二步 第三步 IDEA运行问题 日期问题 代码运行问题 第四步 第五步 第一种 第二种 第六步 第七步 完整代码 运行效果 项目需求 使用Java 开发 零钱通项目&#xff0c;可以完成收益入账&#xff0c;消费&#xff0…

3.1 卷积神经网络基础

文章目录计算机视觉的发展历程卷积神经网络卷积&#xff08;Convolution&#xff09;卷积计算填充&#xff08;padding&#xff09;步幅&#xff08;stride&#xff09;感受野&#xff08;Receptive Field&#xff09;多输入通道、多输出通道和批量操作飞桨卷积API介绍卷积算子…

计算机毕设Python+Vue校园跳蚤平台(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

安卓某通讯协议环境算法浅谈

所有的tlv组包都在 oicq.wlogin_sdk.tlv_type加密算法可以hook oicq.wlogin_sdk.tools Tlv144 是由5个tlv组成 然后用TGTkey进行 TEA加密 tlv_109 AndroidIDtlv_52d 系统内核信息tlv_124 平台网络信息tlv_128 手机设备信息tlv_16e 手机品牌TLV544 是设备id&#xff0…

Kaggle竞赛——Titanic泰坦尼克之灾(0.76315==>0.79186)

Kaggle竞赛网址&#xff1a;https://www.kaggle.com/c/titanic 上一章&#xff1a;Kaggle竞赛——Titanic泰坦尼克之灾&#xff08;保姆级基础版&#xff09; 本次Kaggle泰坦尼克之灾分析过程大致分为&#xff1a; 第1步&#xff1a;了解数据&#xff08;上一章&#xff09; …

共同转债,新化转债上市价格预测

共同转债基本信息转债名称&#xff1a;共同转债&#xff0c;评级&#xff1a;A&#xff0c;发行规模&#xff1a;3.8亿元。正股名称&#xff1a;共同药业&#xff0c;今日收盘价&#xff1a;32.66&#xff0c;转股价格&#xff1a;27.14。当前转股价值 转债面值 / 转股价格 * …

浏览器兼容模式如何设置?只需要跟着下面的步骤设置

许多考生在报考教师资格证或者其他的考试报名&#xff0c;会遇到浏览器兼容设置的问题。与其到时急急忙忙来设置浏览器的兼容模式&#xff0c;不如提前设置好&#xff0c;免了后顾之忧。浏览器兼容模式怎么设置&#xff1f;一起来看看关于浏览器兼容模式的含义以及设置方式吧&a…