Qt-自定义控件鼠标事件键盘事件定时器绘图

news2025/2/22 13:05:12

1. 自定义控件

1.1 创建自定义控件

1.在项目目录上右键, 选择 "Add New"

2.选择 "Qt" --> "Qt 设计师界面类"  

 3.根据需求选择模板,此处选择空窗口

 4.设置类名 和 相关文件名

使用设计师界面类会产生三个文件:.h .cpp .ui

5.通过过ui文件设置控件

1694075445708

 6.在主窗口上设置 SoundWidget 控件

① 打开主窗口 ui 界面 (Widget.ui)

② 将 Widget 拖拽到主窗口中

③ 在 Widget 上点击右键,再选择 "提升为..."

 ④ 填写自定义控件类名,再点击提升

1.2 功能设置

  • 调整数字同时会影响水平滚动条

  • 调整水平滚动条同时影响数字

// 由于 QSpinBox 的信号有两个重载版本,所以需要提前定义信号
void(QSpinBox:: * spSignal)(int) = &QSpinBox::valueChanged;
connect(ui->spinBox, spSignal, ui->horizontalSlider, &QSlider::setValue);

connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);

2. 事件概述

  • 事件 与 信号&槽的功能类似

  • 事件 VS 信号&槽

    • 事件与信号是两个不同层面的东西,发出者不同,作用对象也不同。

    • 事件由外部实体 ( 鼠标、键盘等 ) 生成,事件更偏底层。

    • 信号由按钮等 Qt 对象生成,例如:按钮的 clicked 信号。

    • 使用 Qt 内置组件,一般使用信号&槽; 使用自定义组件时,一般使用事件

  • QWidget 是所有控件的父类,在 Protected Functions 中提供了各种事件的虚函数。子类在继承父类时,自己实现所需要的事件虚函数。

    • 常用事件: 鼠标事件、键盘事件、定时事件、上下文菜单事件、关闭事件、拖放事件、绘制事件等。

QWidget 中的事件定义:

  • 事件对象:事件当中的参数叫做事件对象,内部保存了和事件相关的数据

    • QEvent 是事件对象的基类,其他事件对象都继承该对象。例如: QMouseEvent、QKeyEvent、QWheelEvent等。

举个栗子:

事件与信号并不相同,例如我们使用鼠标点击了一下界面上的按钮,那么就会产生鼠标事件QMouseEvent(不是按钮产生的),而因为按钮被按下了,所以它会发出clicked()单击信号(是按钮产生的)。这里一般只关心按钮的单击信号,而不用考虑鼠标事件,但是如果要设计一个按钮,当鼠标点击按钮时让它产生别的效果,那么就要关心鼠标事件了。

可以看出,事件与信号是两个不同层面的东西,它们的发出者不同,作用也不同。事件由外部实体(例如,按下键盘键、鼠标滚轮)生成,事件更底层。信号需要关注的是产生其的对象(例如按钮),槽函数需要找到信号对象,不会关心如何产生这个信号。如果我们使用已有组件,我们关心的是信号槽;如果我们自定义组件,我们关心的是事件。因为我们可以通过事件来改变组件的默认操作。在Qt中,任何QObject的子类的实例都可以接收和处理事件。

信号槽:signal由具体对象发出,然后会马上交给由connect函数连接的slot进行处理。

事件:Qt使用一个事件队列对所有发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部,前一个事件完成后,取出后面的事件进行处理。但是必要的时候Qt的事件也是可以不进入事件队列,而是直接处理,并且事件还可以使用“事件过滤器”进行过滤。

3. 鼠标事件

3.1 鼠标事件

  • void enterEvent(QEvent *ev): 鼠标进入事件

  • void leaveEvent(QEvent *ev): 鼠标离开事件

  • void mousePressEvent(QMouseEvent *ev); 鼠标按下事件

  • void mouseReleaseEvent(QMouseEvent *ev); 鼠标释放事件

  • void mouseMoveEvent(QMouseEvent *ev); 鼠标移动事件

1.创建自定义组件

2.在ui 结构中调用 MyLabel 控件并提升

 注意:要提升为 QLabel 类型

 3.再头文件中声明事件函数

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QLabel>

class MyLabel : public QLabel
{
  Q_OBJECT
public:
  explicit MyLabel(QWidget *parent = nullptr);

  // 鼠标进入 和 鼠标离开事件
  void enterEvent(QEvent *event);
  void leaveEvent(QEvent *event);

  // 鼠标按下、鼠标离开、鼠标移动事件
  void mousePressEvent(QMouseEvent *ev);
  void mouseReleaseEvent(QMouseEvent *ev);
  void mouseMoveEvent(QMouseEvent *ev);

signals:

public slots:
};

#endif // MYLABEL_H

4.在mylabel.cpp 文件中实现事件

#include <QMouseEvent>

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
	// 设置鼠标追踪时,不需要进行点击也能捕获到鼠标移动事件
  this->setMouseTracking(true);
}

void MyLabel::enterEvent(QEvent *e)
{
    qDebug() << "我进来了";
}
void MyLabel::leaveEvent(QEvent *e)
{
    qDebug() << "我出来了";
}
void MyLabel::mousePressEvent(QMouseEvent *e)
{
    qDebug() << "打我啊笨蛋";
}
void MyLabel::mouseReleaseEvent(QMouseEvent *e)
{
    qDebug() << "啊,我被打了";
}
void MyLabel::mouseMoveEvent(QMouseEvent *e)
{
    qDebug() << "鼠标在移动";
}

3.2 鼠标事件对象

QMouseEvent 事件对象中保存了一些数据

  • button() : 方法能够获取当前使用的是鼠标的哪个按钮,用来区分鼠标的左右键和滚轴

  • pos() \ x() \ y() : 方法能够获取鼠标在组件范围内的坐标

  • windowPos() : 该方法能够获取鼠标在程序窗口中的位置坐标

  • screenPos() : 该方法能够获取鼠标在显示中的位置坐标

void MyLabel::mousePressEvent(QMouseEvent *ev)
{
  if (ev->button() == Qt::LeftButton)
  {
    qDebug() << "打我啊笨蛋" << "左键";
    qDebug() << e->pos() << e->x() << e->y();
    qDebug() << e->windowPos();
    qDebug() << e->screenPos();
  }
  else if (ev->button() == Qt::RightButton)
  {
    qDebug() << "鼠标右键";
  }
  else if (ev->button() == Qt::MidButton)
  {
    qDebug() << "鼠标滚轴按下";
  }
}

3.3 滚轴事件

  • void wheelEvent(QWheelEvent *e) : 滚轴上下滚动时触发

  • 事件对象重要方法:QPoint angleDelta() 获取向上滚动 或者 向下滚动的角度

void MyLabel::wheelEvent(QWheelEvent *e)
{
    qDebug() << e->angleDelta() << e->angleDelta().rx() << e->angleDelta().ry();
    if (e->angleDelta().y() > 0)
    {
        this->setNum(++num);
    }
    else {
        this->setNum(--num);
    }
}

4. 键盘事件

  • keyPressEvent(QKeyEvent *event) : 键盘按下事件

  • keyReleaseEvent(QKeyEvent *event) : 键盘弹起事件

  • 当键盘按下或者弹起时,键盘事件便会被发送给拥有键盘输入焦点的部件,例如:QLineEdit。

  • 键盘事件对象常用方法:

    • key() : 获取当前按键的 ascii 码值

  • 注意事项:

    • 事件会阻止 QLineEdit 的原功能,需要将事件对象return回去以便让原功能正常使用

    • 大键盘有两个回车键,主键盘的回车键匹配 Qt::Key_Return,小键盘的回车键 匹配 Qt::Key_Enter

示例:创建一个自定义的 QInput ,继承与 QLineEdit

MyInput 头文件中定义事件函数

void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);

MyInput 源文件中实现事件函数

void MyInput::keyPressEvent(QKeyEvent *event){
    qDebug() << "按下" << e->key();

    switch (e->key())
    {
        // 匹配esc键
        case Qt::Key_Escape:
            qDebug() << "按下了esc键";
            break;
        // 匹配回车键
        case Qt::Key_Return:
            qDebug() << "按下了enter键";
            break;
    }

    return QLineEdit::keyPressEvent(event);
}
void MyInput::keyReleaseEvent(QKeyEvent *event)
{
    qDebug() << "键盘弹起" << event->key();
}

6. 定时器

6.1 timerEvent

  • timerEvent(QTimerEvent *e) : 定时器事件,继承自 QObject

  • int timerId = startTimer(int num) : 启动定时器,每隔 num 毫秒后执行一次

  • killTimer(int timerId) : 关闭定时器

Widget::Widget(QWidget *parent) : QWidget(parent), Wui(new Ui::Widget)
{
  ui->setupUi(this);

  // 启动定时器
  startTimer(1000);
}

void Widget::timerEvent(QTimerEvent *e)
{
  static int num1 = 1;
  ui->l1->setText(QString::number(num1++));
}

区分多个定时器:

  • 核心: e->timerId() 方法用来获取定时器的 id

  • timer1 、 timer2 需要全局定义,放在 头文件 中

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 启动定时器1
    timer1 = startTimer(1000);

    // 启动定时器2
    timer2 = startTimer(2000);
}

void Widget::timerEvent(QTimerEvent *e)
{
    if(e->timerId() == timer1)
    {
        static int num1 = 1;
        ui->l1->setText(QString::number(num1++));
    }

    if(e->timerId() == timer2)
    {
        static int num2 = 1;
        ui->l2->setText(QString::number(num2++));
    }

}

6.2 QTimer(推荐)

  • QTimer 定时器直接继承与 QObject

  • 使用信号&槽来处理定时器

    • timeout (信号) : 每到一次指定的时间就执行一次代码

  • start(int msec) : 方法能够启动定时器

  • stop方法能够停止定时器

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
	...

  // 另一种方式
  QTimer *timer3 = new QTimer(this);
  timer3->start(500);
	// 使用信号和槽实现定时功能
  connect(timer3, &QTimer::timeout, [this](){
    static int num3 = 1;
    ui->l3->setText(QString::number(num3++));
  });

}

6.3 案例

案例1: 计时器

实现步骤:

  1. 页面布局: 一个 QLabel 用来显示时间, 一个 QPushButton 用来控制计时器的启动和停止

  2. 设置定时器(QTimer)

3)在启动按钮上配置点击信号和槽

// flag 标记是否开始计时
//   true 时,说明开始计时(正在计时),按钮应该显示 暂停
//   false 时,说明暂停计时, 按钮应该显示 开始

QTimer *timer4 = new QTimer(this);
connect(ui->btn, &QPushButton::clicked, [=](){
  if (flag)
  {
    timer4->start(1000);
    ui->btn->setText("暂停");
    flag = false;
  }
  else
  {
    timer4->stop();
    ui->btn->setText("开始");
    flag = true;
  }
});

connect(timer4, &QTimer::timeout, [this](){
	// 使用静态变量来设置计时数字
  static int num = 1;
  QString s = formatTime(num);
  ui->l4->setText(s);
  num++;
});

案例2: 倒计时

ui->countDown->setText("同意(5)");
ui->countDown->setEnabled(false);

QTimer *cTimer = new QTimer(this);
cTimer->start(1000);
connect(cTimer, &QTimer::timeout, [=](){
  timeNum--;
  ui->countDown->setText(QString("同意(%1)").arg(timeNum));
  if (timeNum == 0)
  {
    ui->countDown->setEnabled(true);
    cTimer->stop();
  }
});

案例3: 时钟

QTime t = QTime::currentTime();
ui->timeEdit->setTime(t);

QTimer *clock = new QTimer(this);
clock->start(1000);

connect(clock, &QTimer::timeout, [=](){
  QTime t = QTime::currentTime();
  ui->timeEdit->setTime(t);
});

案例4: 倒计时

// 获取开始时间戳, 即 当前时间戳
QDateTime startTime = QDateTime::currentDateTime();
qDebug() << startTime << startTime.toTime_t();

// 获取指定结束点时间戳
QDateTime endTime(QDate(2023, 10, 12), QTime(3, 0, 0));
qDebug() << endTime << endTime.toTime_t();

时间戳: 从 1970年1月1日 0点0分0秒开始,到某一个时间点的秒数。

unix 纪元, Linux --> 安卓、IOS

2024年5月21日 14:12:43 198493891382

剩余秒数 = 结束时间戳 - 当前时间戳

h = 剩余秒数 / 3600;

m = 剩余秒数 % 3600 / 60;

s = 剩余秒数 % 60;

7. 绘图

绘图也属于事件 paintEvent(QPaintEvent *event)

7.1 画家类

  • QPainter (画家类)用来绘图

  • 常用方法:

    • drawLine() : 绘制直线

    • drawEllipse() :绘制椭圆

    • drawRect() :绘制矩形

    • drawText() :绘制文字

// 指定在当前窗口中画画
QPainter painter(this);

// 绘制直线
painter.drawLine(10, 10, 100, 100);
painter.drawLine(QPoint(500, 0), QPoint(400, 100));

// 绘制椭圆
painter.drawEllipse(100, 100, 50, 50);
painter.drawEllipse(QPoint(400, 100), 80, 40);

// 绘制矩形
painter.drawRect(50, 50, 100, 200);

// 绘制文字
painter.drawText(QPoint(200, 100), "今天天气不错");

7.2 画笔类

  • QPen(画笔类):用来设置画笔的风格,包括:颜色、线条样式、粗细等

  • 常用方法:

    • QPen pen(QColor) : 设置画笔颜色

    • setWidth(int num) : 设置画笔粗细

    • setStyle(enum) : 设置画笔风格

    • painter.setPen(pen) : 让画家使用该画笔

// 设置画笔
QPen rPen(QColor(255, 0, 0));
rPen.setStyle(Qt::DashDotDotLine);
rPen.setWidth(5);

// 让画家使用该画笔
painter.setPen(rPen);

7.3 画刷

  • QBrush(画刷类): 可以为封闭图形填充颜色和样式

  • 常用方法:

    • QBrush brush(QColor): 设置画刷的颜色

    • setStyle() : 设置样式

    • painter.setBrush() : 让画家使用该画刷

void Widget::paintEvent(QPaintEvent *event)
{
  // 指定在当前窗口中画画
  QPainter painter(this);


  // 设置红色画笔
  QPen rPen(QColor(255, 0, 0));
  painter.setPen(rPen);   // 让画家使用红色画笔绘图

  // 绘制直线
  painter.drawLine(10, 10, 100, 100);
  painter.drawLine(QPoint(500, 0), QPoint(400, 100));

  QPen gPen(QColor(0, 255, 0, 100));
  gPen.setStyle(Qt::DashLine);   // 设置线条为虚线
  gPen.setWidth(3);
  painter.setPen(gPen);

  // 绘制椭圆
  painter.drawEllipse(100, 100, 50, 50);
  painter.drawEllipse(QPoint(400, 100), 80, 40);

  QPen pen(QColor(180, 10, 89));
  painter.setPen(pen);

  // 设置画刷
  QBrush brush(QColor(0, 0, 200));
  brush.setStyle(Qt::Dense7Pattern);   // 设置画刷的样式
  painter.setBrush(brush);             // 让画家使用该画刷

  // 绘制矩形
  painter.drawRect(50, 50, 100, 200);

  // 绘制文字
  painter.drawText(QPoint(200, 100), "今天天气不错");

}

7.4 绘制图片

QPixmap 用来绘制图片

绘制图片方法: painter.drawPixmap(QRect(), QPixmap());

painter.drawPixmap(QRect(100, 100, 200, 200), QPixmap(":/images/1.jpg"));

重新绘制图片使用 update() , 该方法属于 QWidget

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->resize(500, 300);

    connect(ui->movePicBtn, &QPushButton::clicked, [=](){
        this->posX += 10;
        this->update();
    });

}

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    if (this->posX > this->width())
    {
        this->posX = 0;
    }
    painter.drawPixmap(QRect(this->posX, 0, 200, 200), QPixmap(":/images/1.jpg"));

}

7.5 绘图设备

QPaintDevice: 绘图设备类是所有绘绘图类的祖先类

7.5.1 QPixmap

QPixmap 对不同的平台进行了显示的优化

示例1: 绘制图形并保存到硬盘

// 创建一个 300*300 的画布
QPixmap pix(300, 300);  
// 为画布设置白色背景
pix.fill(Qt::white);      
// 实例化画家类,并向画布上进行绘画
QPainter painter(&pix); 
// 设置画家使用的画笔颜色
painter.setPen(QColor(12, 190, 88));
// 绘制图形
painter.drawLine(10, 10, 300, 300);
// 将绘制的图形保存成图片
pix.save("d:/123.jpg");

示例2:绘制图片

QPixmap pix;
if(pix.load(":/res/a.png"))
{
  QPainter painter(this);
  // 参数1: x坐标
  // 参数2: y坐标
  // 参数3: 宽度
  // 参数4: 高度
  painter.drawPixmap(0, 0, this->width(), this->height(), pix);

  pix.load(":/res/b.png");
  painter.drawPixmap(10, 30, pix.width() / 2, pix.height() / 2, pix);
}
else
{
  qDebug() << "图片加载失败";
}

7.5.2 QImage

QImage 可以实现像素级操作

示例1: 使用 QImage 进行绘图

// 参数1 | 参数2:  画布的宽和高
// 参数3: 颜色格式
QImage img(300, 300, QImage::Format_RGB32);
// 画布背景色填充
img.fill(Qt::green);
// 让画家在画布上绘制
QPainter painter(&img);
painter.drawRect(QRect(0, 0, 200, 200));

// 保存图片
img.save("d:/222.png");

 示例2: 绘图时修改像素点

void Widget::paintEvent(QPaintEvent *)
{
  QImage img(":/images/1.jpg");
  //    img.load(":/images/1.jpg");     // 两种方式载入图片
  QPainter painter(&img);

  // 使用双循环绘制一个红色的矩形
  for (int i = 0; i < 50; i++)
  {
    for (int j = 0; j < 80; j++)
    {
      QRgb value = qRgb(255, 0, 0);
      img.setPixel(i, j, value);
    }
  }

  painter.drawImage(0, 0, img);
}

7.5.3 QPicture

QPicture 可以记录和重现绘制 (能够对图片进行加密)

QPicture 绘制图片

void Widget::paintEvent(QPaintEvent *e)
{
  QPicture pic;
  QPainter painter;

  // 开始绘制
  painter.begin(&pic);

  painter.drawEllipse(100, 100, 50, 50);

  // 结束绘制
  painter.end();

  // 保存图片
  pic.save("d:/333.abc");
}

 读取自定义后缀的图片

void Widget::paintEvent(QPaintEvent *e)
{
  QPicture pic;
  QPainter painter(this);
  pic.load("d:/123.abc");
  painter.drawPicture(0, 0, pic);
}

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

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

相关文章

媒界:插混VS增程:魏牌蓝山用天花板Hi4诠释都市家庭用车最优解

在新能源混动领域&#xff0c;关于插混、增程谁才是混动最优解&#xff0c;一直业内争论的焦点。正如路遥知马力、日久见人心。对于新能源动力系统的评判标准来说&#xff0c;最好的答案就是路上见。 近日&#xff0c;一位媒体博主驾驶着魏牌全新蓝山从阿拉善到武汉往返狂飙30…

Python面向对象编程:封装和私有属性④

文章目录 1. 引言2. 什么是封装&#xff1f;3. 公有属性和方法4. 私有属性和方法5. 属性访问器&#xff08;Getters 和 Setters&#xff09;6. 使用 property 函数7. 综合示例7.1 项目结构7.2 模块代码__init__.pystudent.pycourse.pymanager.py 7.3 主程序代码main.py 7.4 运行…

cmake模板-支持编译动态/静态文件

代码链接&#xff1a;代码仓库 git clone https://gitee.com/etsuyou/cmake-template.git模板 模板截图 如何使用 在src和inc中写代码 此处用我默认提供的代码 ./go.sh cmake 生成Makefile ./go.sh make 生成bin文件和.a以及.so ./go.sh run app 运行 ./go.sh clean 以…

Tomcat服务部署及优化

一、Tomcat的基本介绍 1. tomcat是什么&#xff1f; Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP程序的首选。一般来说&#xff0c;T…

QT QML 练习8-Simple Transformations

简单的转换&#xff08;Simple Transformations&#xff09; 转换操作改变了一个对象的几何状态。QML元素对象通常能够被平移&#xff0c;旋转&#xff0c;缩放。下面我们将讲解这些简单的操作和一些更高级的用法。 我们先从一个简单的转换开始。用下面的场景作为我们学习的开始…

Python学习100天第9天之面向对象进阶

1 前言 在前面的章节我们已经了解了面向对象的入门知识&#xff0c;知道了如何定义类&#xff0c;如何创建对象以及如何给对象发消息。为了能够更好的使用面向对象编程思想进行程序开发&#xff0c;我们还需要对Python中的面向对象编程进行更为深入的了解。 2 property装饰器…

AVLTree 旋转笔记(根据平衡因子插入的公式,贼好理解)

平衡因子 avltree是一棵每个节点的左右子树的高度差不超过1的二叉树搜索树&#xff0c;对于avltree最重要的就是对平衡因子的控制。 对于旋转我们重点要注意的是三个节点&#xff0c;以左旋举例&#xff0c;需要注意的就是parent&#xff0c;subr&#xff0c;subrl。而旋转的方…

MYSQL架构、执行过程和顺序

MYSQL架构、执行过程和顺序 一、前言 1.1、说明 就MySQL的架构&#xff0c;以及执行过程、sql执行顺序&#xff0c;以及一些相关学习分享内容。 在参考文章的基础上&#xff0c;会增加自己的理解、看法&#xff0c;希望本文章能够在您的学习中提供帮助。 如有错误的地方&a…

Dokcer如何容器部署及常见问题

本文讲解通过Docker部署Jenkins过程及遇到的问题。 通过 Docker 部署 Jenkins 使用 Docker 来部署 Jenkins 是一个快速且高效的方式。以下是使用 Docker 部署 Jenkins 的分步骤指南&#xff1a; 1. 安装 Docker 如果你的系统上还没有安装 Docker&#xff0c;请根据操作系统…

春日技术问答:Spring Boot课程答疑

3系统分析 3.1可行性分析 通过对本课程答疑系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本课程答疑系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

【2D/3D-Lidar-SLAM】 Cartographer详细解读

【2D/3D-Lidar-SLAM】 Cartographer详细解读 1. 摘要 2. Cartographer系统数据处理流程2.1. 数据获取&#xff08;Input Sensor Data&#xff09;2.2 姿态外推器&#xff08;PoseExtrapolator&#xff09;2.3 局部建图&#xff08;Local SLAM&#xff09; 3. 关键模块实现 3.1 …

5、springboot-基础入门

1、系统要求 Java 8 & 兼容java14 .Maven 3.3idea 2019.1.2 1.1、maven设置 修改maven的settings.xml文件中的镜像&#xff0c;如下 <mirrors><mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyu…

vue3 在store的index.js

导入vuex&#xff0c;在store的index.js创建store对象 在main.js挂载store import store from ./storenew Vue ({/* 将store对象实例挂载到vue实例中 所有组件就可以直接从store中获取全局数据了*/ store, render: h > h(App) }).$mount(#app) 在store中的index.js进行声明…

【IPv6】IPv6 NAT66介绍

参考链接 IPv6-to-IPv6 Network Address Translation (NAT66) (ietf.org)https://datatracker.ietf.org/doc/id/draft-mrw-nat66-00.html IPv6 NAT66 NAT66&#xff0c;全称为Network Address Translation for IPv6 to IPv6&#xff0c;是一种用于IPv6网络的地址转换技术。在…

FPGA基于SRIO Auraro 三速以太网 IIC SPI等多协议的高速传输处理项目

高速传输处理项目 此项目涉及较多协议和接口&#xff0c;有较复杂的系统顶层框图设计。在涉及设备较多的应用场景中&#xff0c;需要涉及一款PCI-E板卡&#xff0c;将多个子系统的数据汇总上传到PC或服务器上。在此项目中有3路数据源&#xff0c;分别是:srio数据&#xff0c; …

数据结构与算法:动态规划的深度探讨

目录 12.1 动态规划的核心思想 12.2 经典动态规划问题 12.3 动态规划在图中的应用 12.4 高级动态规划技术 总结 数据结构与算法&#xff1a;动态规划的深度探讨 动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种解决复杂问题的有效方法&#xff0c;特别适…

Nuxt3部署-Ubuntu系统(Node 服务 + pm2 + Nginx 反向代理)

Nuxt3部署-Ubuntu系统&#xff08;Node 服务 pm2 Nginx 反向代理&#xff09; 文章目录 Nuxt3部署-Ubuntu系统&#xff08;Node 服务 pm2 Nginx 反向代理&#xff09;一、安装 Nodejs 环境二、安装 Nginx三、安装 pm2四、本地项目打包1️⃣&#xff1a;打包2️⃣&#xff1…

【截流软件】采集短视频关键词笔记下的筛选评论

用python开发的dy采集工具【爬抖Y搜索评论软件】&#xff0c;可用于引流截流等。 支持2种模式的评论采集&#xff1a; 根据关键词采集评论&#xff0c;爬取思路&#xff1a;作品关键词->作品链接->评论根据作品链接采集评论&#xff0c;爬取思路&#xff1a;作品链接-&g…

aws(学习笔记第六课) AWS的虚拟私有,共有子网以及ACL,定义公网碉堡主机子网以及varnish反向代理

aws(学习笔记第六课) AWS的虚拟私有&#xff0c;共有子网以及ACL&#xff0c;定义公网碉堡主机子网以及varnish反向代理 学习内容&#xff1a; AWS的虚拟私有&#xff0c;共有子网以及ACL定义公网碉堡主机子网&#xff0c;私有子网和共有子网以及varnish反向代理 1. AWS的虚拟…

分享一个中国行政区划多边形2024版(含有十段线)

全国省市县三级行政区划分类 全国有省市县界限数据 十段线 有需要自取