Qt——升级系列(Level Seven):事件、文件

目录

Qt事件

  事件介绍

  事件的处理

  按键事件

  鼠标事件

  定时器

  事件分发器

  事件过滤器

Qt文件

  Qt文件概述

  输入输出设备类

  文件读写类

  文件和目录信息类


Qt事件

  事件介绍

        事件是应⽤程序内部或者外部产⽣的事情或者动作的统称。在 Qt 中使⽤⼀个对象来表⽰⼀个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本⾝在不同的时刻发出的。当⽤⼾按下⿏标、敲下键盘,或者是窗⼝需要重新绘制的时候,都会发出⼀个相应的事件。⼀些事件是在⽤⼾操作时发出,如键盘事件、⿏标事件等,另⼀些事件则是由系统本⾝⾃动发出,如定时器事件。

常⻅的 Qt 事件如下:

常⻅事件描述: 

事件名称
描述
⿏标事件
⿏标左键、⿏标右键、⿏标滚轮,⿏标的移动,⿏标按键的按下和松开
键盘事件
按键类型、按键按下、按键松开
定时器事件
定时时间到达
进⼊离开事件
⿏标的进⼊和离开
滚轮事件
⿏标滚轮滚动
绘屏事件
重绘屏幕的某些部分
显⽰隐藏事件
窗⼝的显⽰和隐藏
移动事件
窗⼝位置的变化
窗⼝事件
是否为当前窗⼝
⼤⼩改变事件
窗⼝⼤⼩改变
焦点事件
键盘焦点移动
拖拽事件
⽤⿏标进⾏拖拽

  事件的处理

        事件处理⼀般常⽤的⽅法为:重写相关的 Event 函数。

        在 Qt 中,⼏乎所有的 Event 函数都是虚函数,所以可以重新实现。如:在实现⿏标的进⼊和离开事件时,直接重新实现 enterEvent() 和 leaveEvent() 即可。

enterEvent() 和 leaveEvent() 函数原型如下:

  按键事件

        Qt 中的按键事件是通过 QKeyEvent 类来实现的。当键盘上的按键被按下或者被释放时,键盘事件便会触发。在帮助⽂档中查找 QKeyEvent 类如下:

        查找按键事件中所有的按键类型:在帮助⽂档中输⼊:Qt::Key,如下图:  

        单个按键的例子

1、单个按键的按下事件: 

void MyWidget::keyPressEvent(QKeyEvent *event) 
{if (event->key() == Qt::Key_A) {qDebug() << "按下了 A 键";// 执行相应的操作}QWidget::keyPressEvent(event);  // 传递事件给父类处理
}

2、单个按键的释放事件: 

void MyWidget::keyReleaseEvent(QKeyEvent *event) 
{if (event->key() == Qt::Key_A) {qDebug() << "释放了 A 键";// 执行相应的操作}QWidget::keyReleaseEvent(event);  // 传递事件给父类处理
}

        组合按键的例子

1、同时按下多个键的事件:

void MyWidget::keyPressEvent(QKeyEvent *event) 
{if (event->modifiers() & Qt::ControlModifier && event->key() == Qt::Key_C) {qDebug() << "同时按下了 Ctrl + C 键";// 执行相应的操作}QWidget::keyPressEvent(event);  // 传递事件给父类处理
}

 2、同时释放多个键的事件:

void MyWidget::keyReleaseEvent(QKeyEvent *event) 
{if (event->modifiers() & Qt::ShiftModifier && event->key() == Qt::Key_F) {qDebug() << "同时释放了 Shift + F 键";// 执行相应的操作}QWidget::keyReleaseEvent(event);  // 传递事件给父类处理
}

在上述示例中:

  • keyPressEvent()keyReleaseEvent() 函数分别处理按键按下和释放事件。
  • 使用 QKeyEvent 对象的 key() 方法获取按下或释放的具体按键。
  • 使用 modifiers() 方法可以获取同时按下的修饰键(如 Ctrl、Shift 等)。
  • 在处理完事件后,通常会调用 QWidget::keyPressEvent(event)QWidget::keyReleaseEvent(event) 将事件传递给父类处理,以确保其他部分的事件处理逻辑能够正常运行。

  鼠标事件

        在 Qt 中,⿏标事件是⽤ QMouseEvent 类来实现的。当在窗⼝中按下⿏标或者移动⿏标时,都会产⽣⿏标事件。

        利⽤ QMouseEvent 类可以获取⿏标的哪个键被按下了以及⿏标的当前位置等信息。在 Qt 帮助⽂档中查找QMouseEvent类 如下图⽰:

        鼠标单击事件的例子

void MyWidget::mousePressEvent(QMouseEvent *event) 
{if (event->button() == Qt::LeftButton) {qDebug() << "左键被按下";// 执行相应的操作} else if (event->button() == Qt::RightButton) {qDebug() << "右键被按下";// 执行相应的操作}QWidget::mousePressEvent(event);  // 传递事件给父类处理
}

        鼠标释放事件的例子

void MyWidget::mouseReleaseEvent(QMouseEvent *event) 
{if (event->button() == Qt::LeftButton) {qDebug() << "左键被释放";// 执行相应的操作} else if (event->button() == Qt::RightButton) {qDebug() << "右键被释放";// 执行相应的操作}QWidget::mouseReleaseEvent(event);  // 传递事件给父类处理
}

        鼠标双击事件的例子

void MyWidget::mouseDoubleClickEvent(QMouseEvent *event) 
{if (event->button() == Qt::LeftButton) {qDebug() << "左键双击";// 执行相应的操作} else if (event->button() == Qt::RightButton) {qDebug() << "右键双击";// 执行相应的操作}QWidget::mouseDoubleClickEvent(event);  // 传递事件给父类处理
}

        鼠标移动事件的例子

void MyWidget::mouseMoveEvent(QMouseEvent *event) 
{qDebug() << "鼠标移动到 (" << event->pos().x() << ", " << event->pos().y() << ")";// 执行相应的操作,例如更新鼠标位置的显示等QWidget::mouseMoveEvent(event);  // 传递事件给父类处理
}

        鼠标滚轮事件的例子 

void MyWidget::wheelEvent(QWheelEvent *event) 
{if (event->delta() > 0) {qDebug() << "鼠标向上滚动";// 执行相应的操作} else if (event->delta() < 0) {qDebug() << "鼠标向下滚动";// 执行相应的操作}QWidget::wheelEvent(event);  // 传递事件给父类处理
}

  定时器

        Qt 中在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定时器就可以实现。所谓定时器就是在间隔⼀定时间后,去执⾏某⼀个任务。定时器在很多场景下都会使⽤到,如弹窗⾃动关闭之类的功能等。

Qt中的定时器分为 QTimerEvent 和 QTimer 这2个类。
        • QTimerEvent类 ⽤来描述⼀个定时器事件。在使⽤时需要通过 startTimer() 函数来开启⼀个定时器,这个函数需要输⼊⼀个以毫秒为单位的整数作为参数来表明设定的时间,它返回的整型值代表这个定时器。当定时器溢出时(即定时时间到达)就可以在 timerEvent() 函数中获取该定时器的编号来进⾏相关操作。
        • QTimer类 来实现⼀个定时器,它提供了更⾼层次的编程接⼝,如:可以使⽤信号和槽,还可以设置只运⾏⼀次的定时器。

QTimerEvent 类

        QTimerEvent类是用来描述定时器事件的类。它通常与 QObjecttimerEvent() 函数结合使用,用于处理定时器事件的回调操作。

使用方法:

  1. 启动定时器: 通过 startTimer() 函数启动一个定时器,该函数接受一个毫秒为单位的时间间隔作为参数,并返回一个整型值,代表该定时器的唯一标识符(定时器编号)。

  2. 定时器事件处理: 当定时器设定的时间间隔到达时,会触发 timerEvent() 函数。在 timerEvent() 函数中,可以通过传入的参数 QTimerEvent *event 来获取定时器的具体信息,例如定时器的标识符,从而执行相应的操作。

  3. 代码示例:

    void MyWidget::timerEvent(QTimerEvent *event) 
    {if (event->timerId() == timerId) {qDebug() << "定时器事件触发,定时器ID:" << event->timerId();// 执行相应的定时操作}QWidget::timerEvent(event);  // 传递事件给父类处理
    }
    

QTimer 类

        QTimer类提供了更高级别的定时器功能,其主要特点是能够通过信号和槽机制来处理定时器事件,以及提供更多的灵活性和控制选项。

主要功能:

  1. 启动定时器: 通过 QTimerstart() 函数启动定时器,该函数接受一个毫秒为单位的时间间隔作为参数,还可以选择性地设置定时器的单次触发或重复触发。

  2. 定时器信号和槽: QTimer 可以通过信号 timeout() 来定期触发定时器事件。可以通过连接(connect)这个信号到槽函数来处理定时器事件,这使得定时器的使用更加方便和直观。

  3. 单次运行定时器: 可以使用 setSingleShot(true) 方法设置定时器为只运行一次,适用于需要在一段时间后执行一次任务的场景。

  4. 代码示例:

    // 创建一个 QTimer 对象
    QTimer *timer = new QTimer(this);// 设置定时器触发的时间间隔,单位为毫秒
    timer->setInterval(1000); // 1秒// 连接定时器的 timeout() 信号到槽函数
    connect(timer, &QTimer::timeout, [=]() 
    {qDebug() << "定时器触发";// 执行相应的定时操作
    });// 启动定时器
    timer->start();
    

区别和选择:

  • QTimerEvent 和 timerEvent(): 适合在自定义的 QObject 派生类中处理定时器事件,需要手动管理定时器的标识符和事件处理逻辑。

  • QTimer 类: 更高级别的接口,通过信号和槽机制处理定时器事件,适合在需要简单设置和操作定时器的场景下使用,无需手动管理定时器事件。

  事件分发器

        概述

        在 Qt 中,事件分发器(Event Dispatcher) 是⼀个核⼼概念,⽤于处理 GUI 应⽤程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承⾃ QObject类 或 QObject类 本⾝都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。

        事件分发器⼯作原理

        在 Qt 中,我们发送的事件都是传给了 QObject 对象,更具体点是传给了 QObject 对象的 event() 函数。所有的事件都会进⼊到这个函数⾥⾯,那么我们处理事件就要重写这个 event() 函数。event() 函数本⾝不会去处理事件,⽽是根据 事件类型(type值)调⽤不同的事件处理函数。事件分发器就是⼯作在应⽤程序向下分发事件的过程中,如下图:

        如上图,事件分发器⽤于分发事件。在此过程中,事件分发器也可以做拦截操作。事件分发器主要是通过 bool event(QEvent *e) 函数来实现。其返回值为布尔类型,若为 ture,代表拦截,不向下分发。

        Qt 中的事件是封装在 QEvent类 中,在 Qt 助⼿中输⼊ QEvent 可以查看其所包括的事件类型,如下图示:

        在Qt中声明和实现鼠标点击事件、事件分发器以及拦截事件时,通常会遵循以下步骤。下面是一个基本的示例,分别在头文件 widget.h 和实现文件 widget.cpp 中展示如何完成这些操作。

widget.h 头文件中声明

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QMouseEvent>class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();protected:// 声明鼠标点击事件处理函数void mousePressEvent(QMouseEvent *event) override;// 声明事件分发器函数bool event(QEvent *event) override;private:// 声明拦截事件处理函数bool eventFilter(QObject *watched, QEvent *event) override;
};#endif // WIDGET_H

widget.cpp 实现文件中实现

#include "widget.h"
#include <QDebug>Widget::Widget(QWidget *parent) : QWidget(parent)
{// 安装事件过滤器,用于拦截事件this->installEventFilter(this);
}Widget::~Widget()
{
}// 实现鼠标点击事件处理函数
void Widget::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {qDebug() << "左键点击,位置:" << event->pos();// 执行相应的操作} else if (event->button() == Qt::RightButton) {qDebug() << "右键点击,位置:" << event->pos();// 执行相应的操作}// 将事件传递给父类处理QWidget::mousePressEvent(event);
}// 实现事件分发器函数
bool Widget::event(QEvent *event)
{if (event->type() == QEvent::MouseButtonPress) {// 处理鼠标按下事件QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);qDebug() << "事件分发器捕获到鼠标按下事件,位置:" << mouseEvent->pos();// 执行相应的操作return true; // 表示事件已处理}// 其他事件交给父类处理return QWidget::event(event);
}// 实现事件过滤器函数
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if (watched == this && event->type() == QEvent::MouseMove) {// 拦截并处理鼠标移动事件QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);qDebug() << "事件过滤器捕获到鼠标移动事件,位置:" << mouseEvent->pos();// 执行相应的操作return true; // 表示事件已处理}// 其他事件交给父类处理return QWidget::eventFilter(watched, event);
}

 代码说明:

  • mousePressEvent 函数: 在该函数中处理鼠标点击事件。根据 QMouseEventbutton() 方法判断是左键还是右键,并可以获取鼠标点击的位置信息。

  • event 函数: 这是事件分发器函数,用于捕获所有类型的事件。在示例中,通过判断事件的类型 (QEvent::MouseButtonPress) 来处理鼠标按下事件。

  • eventFilter 函数: 这是事件过滤器函数,通过调用 installEventFilter() 函数安装到对象上。在示例中,通过判断事件类型 (QEvent::MouseMove) 来处理鼠标移动事件。

  事件过滤器

        在 Qt 中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件,如对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等。通过上⾯的学习,我们已经知道,Qt 创建了 QEvent事件对象之后,会调⽤QObject 的 event()函数 处理事件的分发。显然,我们可以在 event()函数 中实现拦截的操作。由于 event()函数是 protected 的,因此,需要继承已有类。如果组件很多,就需要重写很多个event()函数。这当然相当⿇烦,更不⽤说重写 event()函数还得⼩⼼⼀堆问题。好在 Qt 提供了另外⼀种机制来达到这⼀⽬的:事件过滤器。

        事件过滤器是在应⽤程序分发到 event事件分发器 之前,再做⼀次更⾼级的拦截。如下图⽰:

事件过滤器的⼀般使⽤步骤:
    1、安装事件过滤器;
    2、重写事件过滤器函数:eventfilter() 。 

        假设我们有一个 MyWidget 类,它继承自 QWidget,并希望在该小部件上安装事件过滤器来拦截按键事件。以下是如何在 widget.cpp 中实现这个示例:

#include "widget.h"
#include <QDebug>
#include <QKeyEvent>Widget::Widget(QWidget *parent) : QWidget(parent)
{// 创建一个 QLabel 作为被监视对象QLabel *label = new QLabel("监视对象", this);label->setGeometry(50, 50, 100, 30); // 设置标签的位置和大小// 安装事件过滤器到 label 上label->installEventFilter(this);
}bool Widget::eventFilter(QObject *watched, QEvent *event)
{if (watched->objectName() == "监视对象") {if (event->type() == QEvent::KeyPress) {QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);qDebug() << "按键事件被拦截:按键" << keyEvent->key() << "被按下";// 在此处可以根据需求修改事件或者阻止事件继续传递// 例如,拦截所有按键事件,不让它传递给监视对象return true; // 返回 true 表示事件已处理}}// 其他事件交给父类处理return QWidget::eventFilter(watched, event);
}

示例说明:

  1. 安装事件过滤器:Widget 类的构造函数中,我们创建了一个 QLabel 对象作为被监视对象,并通过 installEventFilter() 函数将当前小部件 (this) 设置为其事件过滤器。

  2. 重写事件过滤器函数:eventFilter() 函数中,我们对事件进行检查和处理。在示例中,我们检查了被监视对象的对象名是否为 "监视对象",如果是,并且事件类型为 QEvent::KeyPress,则我们拦截并处理按键事件。在实际应用中,你可以根据需要修改事件内容、记录日志、阻止事件继续传递等操作。

  3. 返回值解释: 如果事件被处理了并且不需要传递给被监视对象,则返回 true;否则,返回 QWidget::eventFilter(watched, event),以继续将事件传递给父类处理。

Qt文件

  Qt文件概述

        ⽂件操作是应⽤程序必不可少的部分。Qt 作为⼀个通⽤开发库,提供了跨平台的⽂件操作能⼒。 Qt提供了很多关于⽂件的类,通过这些类能够对⽂件系统进⾏操作,如⽂件读写、⽂件信息获取、⽂件复制或重命名等。

  输入输出设备类

        在 Qt 中,⽂件读写的类为 QFile 。QFile 的⽗类为 QFileDevice ,QFileDevice 提供了⽂件交互操作的底层功能。 QFileDevice 的⽗类是 QIODevice,QIODevice 的⽗类为 QObject 。

        QIODevice 是 Qt 中所有输⼊输出设备(input/output device,简称 I/O 设备)的基础类,I/O 设备就是能进⾏数据输⼊和输出的设备,例如⽂件是⼀种 I/O 设备,⽹络通信中的 socket 是 I/O 设备, 串⼝、蓝⽛等通信接⼝也是 I/O 设备,所以它们也是从 QIODevice 继承来的。Qt 中主要的⼀些 I/O 设备类的继承关系如下图所⽰:

上图中各类的说明如下:
        • QFile 是⽤于⽂件操作和⽂件数据读写的类,使⽤ QFile 可以读写任意格式的⽂件。
        • QSaveFile 是⽤于安全保存⽂件的类。使⽤ QSaveFile 保存⽂件时,它会先把数据写⼊⼀个临时⽂件,成功提交后才将数据写⼊最终的⽂件。如果保存过程中出现错误,临时⽂件⾥的数据不会被写⼊最终⽂件,这样就能确保最终⽂件中不会丢失数据或被写⼊部分数据。 在保存⽐较⼤的⽂件或复杂格式的⽂件时可以使⽤这个类,例如从⽹络上下载⽂件等。
        • QTemporaryFile 是⽤于创建临时⽂件的类。使⽤函数 QTemporaryFile::open() 就能创建⼀个⽂件名唯⼀的临时⽂件,在 QTemporaryFile 对象被删除时,临时⽂件被⾃动删除。
        • QTcpSocket 和 QUdpSocket 是分别实现了 TCP 和 UDP 的类。
        • QSerialPort 是实现了串⼝通信的类,通过这个类可以实现计算机与串⼝设备的通信。
        • QBluetoothSocket 是⽤于蓝⽛通信的类。⼿机和平板计算机等移动设备有蓝⽛通信模块,笔记本电脑⼀般也有蓝⽛通信模块。通过QBluetoothSocket类,就可以编写蓝⽛通信程。如编程实现笔记本电脑与⼿机的蓝⽛通信。
        • QProcess 类⽤于启动外部程序,并且可以给程序传递参数。
        • QBuffer 以⼀个 QByteArray 对象作为数据缓冲区,将 QByteArray 对象当作⼀个 I/O 设备来读写。

  文件读写类

        在 Qt 中,⽂件的读写主要是通过 QFile 类来实现。在 QFile 类中提供了⼀些⽤来读写⽂件的⽅法。对于⽂件的操作主要有:
        • 读数据:QFile 类中提供了多个⽅法⽤于读取⽂件内容;如 read()、readAll()、readLine()等。
        • 写数据:QFile 类中提供了多个⽅法⽤于往⽂件中写内容;如 write()、writeData()等。
        • 关闭⽂件:⽂件使⽤结束后必须⽤函数 close() 关闭⽂件。

        访问⼀个设备之前,需要使⽤ open()函数 打开该设备,⽽且必须指定正确的打开模式,QIODevice 中所有的打开模式由 QIODevice::OpenMode 枚举变量定义,其取值如下:

QIODevice::NotOpen
没有打开设备
QIODevice::ReadOnly
以只读⽅式打开设备
QIODevice::WriteOnly
以只写⽅式打开设备
QIODevice::ReadWrite
以读写⽅式打开设备
QIODevice::Append
以追加⽅式打开设备,数据将写到⽂件末尾
QIODevice::Truncate
每次打开⽂件后重写⽂件内容,原内容将被删除
QIODevice::Text
在读⽂件时,⾏尾终⽌符会被转换为 '\n';当写⼊⽂件时,⾏尾终⽌符会被转换为 本地编码。如 Win32上为'\r\n';
QIODevice::Unbuffered
⽆缓冲形式打开⽂件,绕过设备中的任何缓冲区
QIODevice::NewOnly
⽂件存在则打开失败,不存在则创建⽂件

  文件和目录信息类

        QFileInfo 是 Qt 提供的⼀个⽤于获取⽂件和⽬录信息的类,如获取⽂件名、⽂件⼤⼩、⽂件修改⽇期等。QFileInfo类中提供了很多的⽅法,常⽤的有:
        • isDir() 检查该⽂件是否是⽬录;
        • isExecutable() 检查该⽂件是否是可执⾏⽂件;
        • fileName() 获得⽂件名;
        • completeBaseName() 获取完整的⽂件名;
        • suffix() 获取⽂件后缀名;
        • completeSuffix() 获取完整的⽂件后缀;
        • size() 获取⽂件⼤⼩;
        • isFile() 判断是否为⽂件;
        • fileTime() 获取⽂件创建时间、修改时间、最近访问时间等;

代码示例:

#include <QCoreApplication>
#include <QFileInfo>
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建一个 QFileInfo 对象,传入文件路径或者文件名QFileInfo fileInfo("/path/to/your/file.txt");// 获取文件名QString fileName = fileInfo.fileName();qDebug() << "文件名:" << fileName;// 获取文件路径QString filePath = fileInfo.filePath();qDebug() << "文件路径:" << filePath;// 获取文件大小(字节)qint64 fileSize = fileInfo.size(); // 返回 qint64 类型qDebug() << "文件大小:" << fileSize << "bytes";// 获取文件修改日期和时间QDateTime lastModified = fileInfo.lastModified();qDebug() << "最后修改时间:" << lastModified.toString(Qt::ISODate);// 获取文件后缀名QString suffix = fileInfo.suffix();qDebug() << "文件后缀名:" << suffix;// 检查文件是否存在if (fileInfo.exists()) {qDebug() << "文件存在";} else {qDebug() << "文件不存在";}return a.exec();
}

 示例说明:

  1. 包含头文件: 引入了 QFileInfo 类的头文件 <QFileInfo>,以及用于调试输出的 <QDebug>

  2. 创建 QFileInfo 对象: 使用文件路径或文件名创建一个 QFileInfo 对象,例如 "/path/to/your/file.txt"

  3. 获取文件信息:

    • 使用 fileName() 获取文件名。
    • 使用 filePath() 获取文件路径。
    • 使用 size() 获取文件大小,返回 qint64 类型表示文件大小的字节数。
    • 使用 lastModified() 获取文件最后修改时间,返回 QDateTime 对象。
    • 使用 suffix() 获取文件后缀名。
  4. 检查文件存在性: 使用 exists() 函数检查文件是否存在,并根据结果输出相应信息。

  5. 输出信息: 使用 qDebug() 输出获取到的文件信息。

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

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

相关文章

工商业光伏项目如何快速开发?

一、前期调研与规划 1、屋顶资源评估&#xff1a;详细测量屋顶面积、承重能力及朝向&#xff0c;利用光伏业务管理软件进行日照分析和发电量预测&#xff0c;确保项目可行性。 2、政策与补贴研究&#xff1a;深入了解当地政府对工商业光伏项目的政策支持和补贴情况&#xff0…

Java面试过程中遇到的问题

Java面试过程中遇到的问题 介绍工作经验项目 介绍项目 为什么选用这个技术 报表服务怎么实现的 java框架 1、spring clound特性&#xff0c;组件有那些以及作用 springCloud是一套微服务组件&#xff0c; 常用的Eureka&#xff0c;Ribbon&#xff0c;Hystrix&#xff0c;Fe…

第三方支付平台如何完美契合跨境电商?

在全球化的大潮中&#xff0c;跨境电商"Eurasia Boutique"的创始人艾米丽&#xff0c;带着她的梦想和手工艺品&#xff0c;踏上了进入中国市场的征程。这是一个充满挑战和机遇的旅程&#xff0c;艾米丽和她的企业需要面对和解决一系列复杂的问题。 合规的门槛 艾米…

JVM原理(十四):JVM虚拟机运行时栈帧结构

Java虚拟机已方法作为最基本的执行单位。 栈帧&#xff1a;是支持Java虚拟机进行方法调用和方法执行背后的数据结构。 栈帧存储了方法的 局部变量表、操作数栈、动态连接和放回地址等信息。 每一个方法的调用开始和执行结束&#xff0c;都对应着一个栈帧在虚拟机栈里面从入栈…

Linux文件与日志

目录 1. Linux 文件系统 1.1 inode号 1.2 EXT类型文件恢复 1.3 xfs类型文件备份和恢复 2. 日志分析 2.1 日志类型 2.2日志配置文件 2.3 日志分析的重要性 在Linux系统中&#xff0c;文件和日志是管理和维护系统运行所不可或缺的。理解它们的工作原理和如何有效地管理和…

驱动开发:配置Visual Studio驱动开发环境

100编程书屋_孔夫子旧书网 配置驱动开发环境配置驱动开发模板配置驱动双机调试 在正式开始驱动开发之前&#xff0c;需要自行搭建驱动开发的必要环境&#xff0c;首先我们需要安装Visual Studio 2013这款功能强大的程序开发工具&#xff0c;在课件内请双击ISO文件并运行内部的…

2009-2024年第一季度上市公司华证ESG评级季度数据

2009-2024年第一季度上市公司华证ESG评级季度数据 1、时间&#xff1a;2009-2024年第一季度 2、指标&#xff1a;证券代码、证券简称、评级日期、综合评级、综合得分、E评级、E得分、S评级、S得分、G评级、G得分、证监会行业&#xff08;新&#xff09;、同花顺行业&#xff…

Visio框图自动带填充色原因及如何取消

0 Preface/Foreword Visio&#xff0c;Windows的一个流程图&框图制作工具。 1 新建Visio文件 1.1 图形带填充 新建Visio时候&#xff0c;如果选择了模版&#xff0c;那么就后期使用的工具元素会自动填充。 带来的弊端&#xff0c;在元素编辑文字时&#xff0c;如果此时不…

苹果公司的Wifi定位服务(WPS)存在被滥用的风险

安全博客 Krebs on Security 2024年5月21日发布博文&#xff0c;表示苹果公司的定位服务存在被滥用风险&#xff0c;通过 "窃取"WPS 数据库&#xff0c;可以定位部队行踪。 相关背景知识 手机定位固然主要依赖卫星定位&#xff0c;不过在城市地区&#xff0c;密集的…

Perl 语言开发(五):循环语句

目录 1. 循环语句概述 2. while 循环 2.1 基本语法 2.2 示例 2.3 无限循环 3. until 循环 3.1 基本语法 3.2 示例 3.3 无限循环 4. for 循环 4.1 基本语法 4.2 示例 4.3 嵌套循环 5. foreach 循环 5.1 基本语法 5.2 示例 5.3 遍历哈希 6. 循环控制语句 6.1 …

新建Vue工程的几种方法

文章目录 使用CLI2 : vue-cli使用CLI3 : vue/cli使用 vue3构建 &#xff08;内置Vite&#xff09;直接使用Vite使用parcel (最少配置方案) 使用CLI2 : vue-cli vue-cli是针对构建vue的脚手架CLI2&#xff0c;只能新建vue2工程。 全局安装vue-cli之后&#xff0c;构建vue2项目的…

03.C1W2.Sentiment Analysis with Naïve Bayes

目录 Probability and Bayes’ RuleIntroductionProbabilitiesProbability of the intersection Bayes’ RuleConditional ProbabilitiesBayes’ RuleQuiz: Bayes’ Rule Applied Nave Bayes IntroductionNave Bayes for Sentiment Analysis P ( w i ∣ c l a s s ) P(w_i|clas…

大数据领域的深度分析——AI是在帮助开发者还是取代他们?

在大数据领域&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;的应用正在迅速扩展&#xff0c;改变了数据科学家和开发者的工作方式。本文将从大数据的专业视角&#xff0c;探讨AI工具在这一领域的作用&#xff0c;以及它们是如何帮助开发者而非取代他们的。 1. 大数据…

npm 淘宝镜像证书过期,错误信息 Could not retrieve https://npm.taobao.org/mirrors/node/latest

更换 npm 证书 问题描述报错原因更换步骤1 找到 nvm 安装目录2 发现证书过期3 更换新地址4 保存后&#xff0c;重新安装成功 问题描述 在使用 nvm 安装新版本时&#xff0c;未成功&#xff0c;出现报错&#xff1a; Could not retrieve https://npm.taobao.org/mirrors/node/l…

【postgresql】表操作

创建表 (CREATE TABLE): CREATE TABLE table_name ( column1 data_type constraint,column2 data_type constraint,... ); 插入数据 (INSERT INTO): INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...); 查询数据 (SELECT): SELECT column1, c…

火山引擎数据飞轮实践:在电商场景中,如何建设全链路数据血缘?

数据作为新型生产要素&#xff0c;正支撑企业的数智化转型。但企业数字化建设也存在管理成本高、数据产品使用门槛高、数据资产价值不够的问题&#xff0c;其原因在于业务和数据之间没有形成双向良性驱动。 结合新时代企业数字化转型需求&#xff0c;火山引擎基于字节跳动十余…

IC烧录员-带着工程师的梦想远航!

如果说软件工程师是代码程序的创造者&#xff0c;那么IC烧录员就是把工程师们辛苦敲代码&#xff0c;日夜辛劳的成果烧录到芯片里面的实践者&#xff0c;是他们&#xff0c;让工程师们的梦想运用到实践中&#xff0c;是他们带着工程师的梦想远航&#xff0c;他们的薪酬或许没有…

第一节-k8s架构图

一个Deployment&#xff0c;可以由多个不同Node下的Pod组成&#xff0c;每个Pod又由多个Container组成。 区分Deployment是用Labels(key:value)&#xff0c;区分Pod是用PodName&#xff0c;区分Container是用ContainerName。 一个Node可以包含多个不同Deployment中的pod&…

MySQL-作业1

一、数据库 1、登陆数据库 2、创建数据库zoo 3、修改数据库zoo字符集为gbk 4、选择当前数据库为zoo 5、查看创建数据库zoo信息 6、删除数据库zoo 二、创建表 1、创建一个名称为db_system的数据库 2、在该数据库下创建两张表&#xff0c;具体要求如下&#xff1a; 员工表 user …

米国政府呼吁抛弃 C 和 C++

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 很多观点认为C 或 C永远不可被…