Qt中实现让静态图片动起来,创建动画效果

在现代应用程序开发中,动画效果是提升用户体验的重要元素之一。Qt作为一个强大的跨平台应用程序框架,提供了丰富的工具和库来创建各种动画效果。本文将介绍如何在Qt中使用静态图片创建动画效果。

实现方法一

使用QTimer和QPixmap

1.准备图片资源:

首先,确保你有一系列连续的静态图片,这些图片将构成动画帧。

将这些图片添加到Qt项目的资源文件中。

2.创建UI界面:

如果需要,可以在Qt Designer或代码中设计一个窗口用于显示动画。

3.编写动画类:

定义一个类,该类包含一个QLabel用于显示图片,以及一个QTimer用于控制动画帧的切换。

4.初始化图片:

在类的构造函数或初始化函数中,使用QPixmap加载图片资源,并存储到数组或其他数据结构中以便循环使用。

5.设置定时器:

设置QTimer的间隔时间,这将决定动画播放的速度。

连接定时器的timeout信号到槽函数,该槽函数负责切换到下一帧图片。

6.绘制图片:

在槽函数中,使用QLabel的setPixmap方法切换显示的图片。

可以通过索引递增来选择下一帧图片,并在到达最后一帧后循环回第一帧。

7.开始动画:

在适当的位置(比如窗口显示后),启动定时器。

示例代码:

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QPixmap>
#include <QResource>class AnimatedWidget : public QWidget {Q_OBJECTpublic:AnimatedWidget(QWidget *parent = nullptr) : QWidget(parent), currentFrame(0) {// 初始化QLabel用于显示图片QLabel *label = new QLabel(this);QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(label);setLayout(layout);// 加载资源文件中的图片for (int i = 1; i <= frameCount; ++i) {QString fileName = QString(":/images/frame%1.png").arg(i, 2, 10, QLatin1Char('0'));frames.append(QPixmap(fileName));}// 设置定时器timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &AnimatedWidget::nextFrame);timer->start(frameInterval); // 假设frameInterval为每帧间隔毫秒数// 显示第一帧label->setPixmap(frames[currentFrame]);}private slots:void nextFrame() {currentFrame = (currentFrame + 1) % frames.size();QLabel *label = findChild<QLabel*>("");if (label)label->setPixmap(frames[currentFrame]);}private:int currentFrame;QList<QPixmap> frames;QTimer *timer;const int frameCount = 10; // 图片帧数量const int frameInterval = 100; // 每帧间隔时间,例如100毫秒
};int main(int argc, char *argv[]) {QApplication a(argc, argv);AnimatedWidget w;w.show();return a.exec();
}

实现方法二

例如要让一张静态的风扇图片在Qt中旋转,可以使用动画框架中的QPropertyAnimationQTimer配合QTransform来实现。以下是一个通过QTimerQTransform实现旋转的示例。

首先,准备好风扇的静态图片,并确保您已经安装并配置好了Qt开发环境。

  1. 创建一个新的Qt Widgets应用程序项目。

  2. 在您的mainwindow.ui文件中添加一个QLabel控件,并设置其pixmap属性以显示风扇的图片。

  3. mainwindow.h文件中,定义一个QTimer对象和一个角度变量,用于控制图片的旋转:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QTimer>
#include <QPixmap>
#include <QTransform>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void rotateFan();private:Ui::MainWindow *ui;QTimer *timer;QPixmap fanPixmap;int angle;
};#endif // MAINWINDOW_H
在mainwindow.cpp文件中,初始化计时器和旋转逻辑:
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow), angle(0)
{ui->setupUi(this);// 加载风扇图片fanPixmap = QPixmap(":/path/to/your/fan/image.png");// 设置图片到QLabelui->label->setPixmap(fanPixmap);// 创建定时器对象timer = new QTimer(this);// 连接定时器的timeout信号到rotateFan槽函数connect(timer, &QTimer::timeout, this, &MainWindow::rotateFan);// 设置定时器每隔30毫秒触发一次timer->start(30);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::rotateFan()
{// 更新轮转角度angle = (angle + 5) % 360;// 创建旋转变换QTransform transform;transform.rotate(angle);// 应用旋转并更新QLabel显示的图片QPixmap rotatedPixmap = fanPixmap.transformed(transform, Qt::SmoothTransformation);ui->label->setPixmap(rotatedPixmap);
}

在这个示例中,我们首先加载了风扇图片并设置到QLabel。接着创建一个QTimer对象,每隔30毫秒触发一次rotateFan槽函数。在rotateFan槽函数中,我们增加角度,然后使用QTransform对象对图片进行旋转,并将旋转后的图片设置回QLabel。

需要确保您的图片路径正确,您可以在项目配置文件中配置资源文件来简化路径管理。

通过这种方法,您可以轻松创建一个旋转的风扇效果。一些素材可以从网上获取,但是图片背景和颜色等可能都不如意,那么接下来介绍下Python的图片处理,可以不使用ps等图片处理工具的情况下,对素材进行一些简单的处理,如jpg转png实现背景透明效果,或者去除或跟换图片背景等。

Python的PIL库 介绍

Python Imaging Library(PIL)是一个非常流行的Python库,用于处理图像。尽管它的名字仍然广泛使用,但实际上,PIL已经被其分支Pillow所取代,Pillow不仅提供了PIL的所有特性,还增加了更多功能和对最新Python版本的支持。下面是对Pillow库的基本介绍:

安装

Pillow可以通过pip轻松安装:

pip install Pillow

主要功能

Pillow库支持多种图像处理功能,包括但不限于:

读取和保存图像:支持多种图像格式,如JPEG、PNG、BMP、GIF、TIFF等。

基本操作:裁剪、旋转、翻转图像,调整图像大小,改变图像模式(如灰度、RGB、CMYK)。

颜色操作:调整亮度、对比度、色调、饱和度,以及应用各种滤镜和效果。

文字和图像合并:在图像上绘制文本或叠加其他图像。

图像分析:获取图像的元数据,统计直方图,进行基本的图像识别任务。

图像序列处理:处理动画GIF或连续帧图像。

高级功能:包括图像增强、格式转换、简单的图像识别和机器学习集成等。

常用类和方法

Image: 这是Pillow中最核心的类,用于打开、操作和保存图像。
Image.open: 用于打开图像文件。
Image.save: 保存图像到文件。
Image.show: 显示图像。
Image.resize: 改变图像尺寸。
Image.crop: 裁剪图像。
Image.rotate: 旋转图像。
Image.filter: 应用过滤器或效果到图像。
ImageDraw: 提供在图像上绘图的功能,如画线、圆、文本等。
ImageFont: 用于设置绘图时使用的字体。
ImageEnhance: 提供图像增强功能,如亮度、对比度、锐化等。

示例代码

from PIL import Image# 打开图像
img = Image.open('example.jpg')# 调整图像大小
img_resized = img.resize((800, 600))# 保存修改后的图像
img_resized.save('example_resized.jpg')# 显示图像
img.show()

JPG格式图片本身不支持透明度,因此不能直接保存为带有透明背景的图片。若要移除JPG图片的白色背景并使其透明,你需要先将图片转换为支持透明度的格式,如PNG,然后去除白色背景。

如果图片分辨率很大,你可以在去除白色背景之后,或者在处理之前,先调整图片的大小以适应你的需求。使用Pillow库,你可以很容易地实现图片的缩放。下面是在原有代码基础上增加图片尺寸。

调整的示例:

from PIL import Imagedef resize_and_remove_white_background(input_path, output_path, max_size=None):# 打开图片img = Image.open(input_path)# 如果指定了最大尺寸,则进行缩放if max_size:img.thumbnail(max_size, resample=Image.Resampling.LANCZOS)  # 使用LANCZOS代替ANTIALIAS进行高质量缩放# 转换为RGBA模式img = img.convert("RGBA")# 定义去除白色背景的函数def remove_white(pixel):if pixel[:3] == (255, 255, 255):  # 检查像素是否为白色return (255, 255, 255, 0)  # 设置为透明else:return pixel# 应用函数到每个像素img_data = img.getdata()new_data = list(map(remove_white, img_data))# 创建新图像并应用处理后的数据img_with_transparency = Image.new("RGBA", img.size)img_with_transparency.putdata(new_data)# 保存为PNGimg_with_transparency.save(output_path, "PNG")# 使用函数,传入图片路径、输出路径和可选的最大尺寸(例如,(800, 600))
input_jpg = "fan.jpg"
output_png = "fan.png"
max_dimensions = (200, 200)  # 例子:最大宽度200,最大高度200
resize_and_remove_white_background(input_jpg, output_png, max_size=max_dimensions)
print(f"Image saved as: {output_png}")

实现风扇旋转效果 

以下是我的自定义Widget实现的风扇旋转效果封装类:

#include "fanwidget.h"
#include <QTimer>
#include <QPainter>
#include <QTransform>FanWidget::FanWidget(QWidget *parent): QWidget(parent),angle_(0),isRotating_(false),rotationTimer_(new QTimer(this))
{QPixmap pixmap_ = QPixmap(":/image/fan.png"); // 确保路径正确if(pixmap_.isNull()){qDebug("pixmap_ is null");}if(!pixmap_.isNull()){// 获取Widget当前的宽度和高度int widgetWidth = width();int widgetHeight = height();// 计算图片显示的最大宽度和高度,以适应Widget的尺寸,同时保持宽高比int pixmapWidth = pixmap_.width();int pixmapHeight = pixmap_.height();float ratio = qMin(static_cast<float>(widgetWidth) / pixmapWidth,static_cast<float>(widgetHeight) / pixmapHeight);int scaledWidth = static_cast<int>(pixmapWidth * ratio);int scaledHeight = static_cast<int>(pixmapHeight * ratio);// 缩放图片scaledPixmap_1 = pixmap_.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);}pixmap_ = QPixmap(":/image/fan1.png"); // 确保路径正确if(pixmap_.isNull()){qDebug("pixmap_ is null");}if(!pixmap_.isNull()){// 获取Widget当前的宽度和高度int widgetWidth = width();int widgetHeight = height();// 计算图片显示的最大宽度和高度,以适应Widget的尺寸,同时保持宽高比int pixmapWidth = pixmap_.width();int pixmapHeight = pixmap_.height();float ratio = qMin(static_cast<float>(widgetWidth) / pixmapWidth,static_cast<float>(widgetHeight) / pixmapHeight);int scaledWidth = static_cast<int>(pixmapWidth * ratio);int scaledHeight = static_cast<int>(pixmapHeight * ratio);// 缩放图片scaledPixmap_2 = pixmap_.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);}connect(rotationTimer_, &QTimer::timeout, this, &FanWidget::rotateFan);
}FanWidget::~FanWidget()
{// 如果有资源需要清理,可以在这里做
}void FanWidget::startRotation()
{if (!isRotating_) {isRotating_ = true;rotationTimer_->start(30);}
}void FanWidget::stopRotation()
{if (isRotating_) {isRotating_ = false;rotationTimer_->stop();angle_ = 0;update();}
}void FanWidget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.translate(width() / 2, height() / 2);painter.rotate(angle_);if(!fanPixmap_.isNull()){// 获取Widget当前的宽度和高度int widgetWidth = width();int widgetHeight = height();// 计算图片显示的最大宽度和高度,以适应Widget的尺寸,同时保持宽高比int pixmapWidth = fanPixmap_.width();int pixmapHeight = fanPixmap_.height();float ratio = qMin(static_cast<float>(widgetWidth) / pixmapWidth,static_cast<float>(widgetHeight) / pixmapHeight);int scaledWidth = static_cast<int>(pixmapWidth * ratio);int scaledHeight = static_cast<int>(pixmapHeight * ratio);// 缩放图片QPixmap scaledPixmap = fanPixmap_.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);// 根据缩放后的图片尺寸计算中心位置int x = (widgetWidth) / 2;int y = (widgetHeight) / 2;painter.drawPixmap(-x, -y, scaledPixmap);}//painter.drawPixmap(-fanPixmap_.width() / 2, -fanPixmap_.height() / 2, fanPixmap_);// 注意:背景颜色的控制逻辑也应该放在这里,具体实现见之前的说明
}// rotateFan槽函数的实现如果之前没有在.h中声明,则也应在此处定义
void FanWidget::rotateFan()
{if (isRotating_) {angle_ += 5;if (angle_ >= 360) angle_ -= 360;update();}
}
#include "fanwidget.h"
#include <QTimer>
#include <QPainter>
#include <QTransform>FanWidget::FanWidget(QWidget *parent): QWidget(parent),angle_(0),isRotating_(false),rotationTimer_(new QTimer(this))
{QPixmap pixmap_ = QPixmap(":/image/fan0.png"); // 确保路径正确if(pixmap_.isNull()){qDebug("pixmap_ is null");}if(!pixmap_.isNull()){// 获取Widget当前的宽度和高度int widgetWidth = width();int widgetHeight = height();// 计算图片显示的最大宽度和高度,以适应Widget的尺寸,同时保持宽高比int pixmapWidth = pixmap_.width();int pixmapHeight = pixmap_.height();float ratio = qMin(static_cast<float>(widgetWidth) / pixmapWidth,static_cast<float>(widgetHeight) / pixmapHeight);int scaledWidth = static_cast<int>(pixmapWidth * ratio);int scaledHeight = static_cast<int>(pixmapHeight * ratio);// 缩放图片scaledPixmap_1 = pixmap_.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);}pixmap_ = QPixmap(":/image/fan1.png"); // 确保路径正确if(pixmap_.isNull()){qDebug("pixmap_ is null");}if(!pixmap_.isNull()){// 获取Widget当前的宽度和高度int widgetWidth = width();int widgetHeight = height();// 计算图片显示的最大宽度和高度,以适应Widget的尺寸,同时保持宽高比int pixmapWidth = pixmap_.width();int pixmapHeight = pixmap_.height();float ratio = qMin(static_cast<float>(widgetWidth) / pixmapWidth,static_cast<float>(widgetHeight) / pixmapHeight);int scaledWidth = static_cast<int>(pixmapWidth * ratio);int scaledHeight = static_cast<int>(pixmapHeight * ratio);// 缩放图片scaledPixmap_2 = pixmap_.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);}connect(rotationTimer_, &QTimer::timeout, this, &FanWidget::rotateFan);
}FanWidget::~FanWidget()
{// 如果有资源需要清理,可以在这里做
}void FanWidget::startRotation()
{if (!isRotating_) {isRotating_ = true;rotationTimer_->start(30);}
}void FanWidget::stopRotation()
{if (isRotating_) {isRotating_ = false;rotationTimer_->stop();angle_ = 0;update();}
}void FanWidget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.translate(width() / 2, height() / 2);painter.rotate(angle_);QPixmap pixmap_;if (isRotating_){pixmap_ = scaledPixmap_1;}else {pixmap_ = scaledPixmap_2;}if(!pixmap_.isNull()){// 获取Widget当前的宽度和高度int widgetWidth = pixmap_.width();int widgetHeight = pixmap_.height();int x = (widgetWidth) / 2;int y = (widgetHeight) / 2;painter.drawPixmap(-x, -y, pixmap_);}
}// rotateFan槽函数的实现如果之前没有在.h中声明,则也应在此处定义
void FanWidget::rotateFan()
{if (isRotating_) {angle_ += 5;if (angle_ >= 360) angle_ -= 360;update();}
}void FanWidget::setScaledPixmap_1(const QPixmap &pixmap)
{int widgetWidth =width();int widgetHeight = height();// 计算图片显示的最大宽度和高度,以适应Widget的尺寸,同时保持宽高比int pixmapWidth = pixmap.width();int pixmapHeight = pixmap.height();float ratio = qMin(static_cast<float>(widgetWidth) / pixmapWidth,static_cast<float>(widgetHeight) / pixmapHeight);int scaledWidth = static_cast<int>(pixmapWidth * ratio);int scaledHeight = static_cast<int>(pixmapHeight * ratio);// 缩放图片QPixmap pixmap_ = pixmap.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);scaledPixmap_1 = pixmap_;
}
#ifndef FANWIDGET_H
#define FANWIDGET_H#include <QWidget>
#include <QPixmap>QT_BEGIN_NAMESPACE
class QTimer;
class QPaintEvent;
class QPainter;
class QTransform;
QT_END_NAMESPACEclass FanWidget : public QWidget
{Q_OBJECTpublic:explicit FanWidget(QWidget *parent = nullptr);~FanWidget();void setScaledPixmap_1(const QPixmap &pixmap);public slots:void startRotation();void stopRotation();protected:void paintEvent(QPaintEvent *) override;private slots:void rotateFan();
private:QPixmap fanPixmap_;QPixmap scaledPixmap_1;QPixmap scaledPixmap_2;int angle_;QTimer *rotationTimer_;bool isRotating_;Q_DISABLE_COPY(FanWidget)
};
#endif // FANWIDGET_H

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

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

相关文章

Qt图形与图片(Qt位置相关函数、Qt基础图形的绘制、双缓冲机制、显示SVG格式图片)

此篇文章介绍几种主要位置函数及其之间的区别&#xff0c;以及各种与位置相关函数的使用场合&#xff1b;然后&#xff0c;通过一个简单绘图工具实例&#xff0c;介绍利用QPainter和QPainterPath两种方法绘制各种基础图形&#xff1b;最后&#xff0c;通过几个实例介绍如何利用…

GD32F303RET6读取SGM58031电压值

1、SGM58031芯片详解 &#xff08;1&#xff09;SGM58031是一款低功耗&#xff0c;16位精度&#xff0c;delta-sigma (ΔΣ)模数转换器(ADC)。它从3V到5.5V供电。 &#xff08;2&#xff09;SGM58031包含一个片上参考和振荡器。它有一个I2C兼容接口&#xff0c;可以选择四个I2…

【RHCE】系统服务综合实验

一、实验内容 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供 www.rhce.com 虚拟主机 4、该虚拟主机的documentroot目录在 /nfs/rhce 目录 5、该目录由 node02…

Python | Leetcode Python题解之第229题多数元素II

题目&#xff1a; 题解&#xff1a; class Solution:def majorityElement(self, nums: List[int]) -> List[int]:cnt {}ans []for v in nums:if v in cnt:cnt[v] 1else:cnt[v] 1for item in cnt.keys():if cnt[item] > len(nums)//3:ans.append(item)return ans

为什么渲染农场渲染的是帧,而不是视频?

在3D动画产业的壮阔画卷中&#xff0c;渲染农场作为幕后英雄&#xff0c;以其庞大的计算能力支撑起无数视觉奇观的诞生。这些由高性能计算机集群构成的系统&#xff0c;通过独特的逐帧渲染策略&#xff0c;解锁了单机难以企及的创作自由与效率。本文将深入剖析这一策略背后的逻…

maven7——(重要,构建项目)maven项目构建(命令)

Maven的常用命令管理项目的生命周期 clean命令 清除编译产生的target文件夹内容&#xff0c;可以配合相应命令在cmd中使用&#xff0c;如mvn clean package&#xff0c; mvn clean test D:\工作\公司培训-4班\day20\day20\untitled1>mvn clean compile命令 该命令可以…

机器学习开源分子生成系列(2)-基于三维形状和静电相似性的DeepFMPO v3D安装及使用

前言 本文是基于 3D 的分子生成方法DeepFMPO v3D的介绍及安装使用。 一、DeepFMPO v3D是什么&#xff1f; github代码介绍文章 在药物发现中&#xff0c;如何寻找具新颖性和结构多样性的候选分子是颇受药物设计科学家关注的问题。通过虚拟筛选的化学空间搜索往往会受限于筛选…

牛顿力学和拉格朗日力学求解atwood machine问题对比

一个半径为 R R R、转动惯量为 I I I 的圆盘。绳子与圆盘无滑动&#xff0c;质量 m 2 m_2 m2​ 的物体在重力 g g g 作用下下坠&#xff0c;带动质量 m 1 m_1 m1​ 的物体上升。求 m 1 m_1 m1​和 m 2 m_2 m2​ 的加速度 a a a。 牛顿力学方法 对质量 m 1 m_1 m1​ 和 …

Web 性能入门指南-1.2 分析在线零售 Web 性能及优化方向

让顾客满意是零售业成功的秘诀。事实证明&#xff0c;提供快速、一致的在线体验可以显著提高零售商关心的每项指标——从转化率和收入到留存率和品牌认知度。 本文大纲&#xff1a; 页面速度影响在线零售业务数据 如何将您的网站速度与竞争对手进行比较 性能优化入门&#xf…

Scanner工具类

扫描控制台输入 1.nextLine nextLine() 方法会扫描输入流中的字符&#xff0c;直到遇到行末尾的换行符 \n&#xff0c;然后将该行的内容作为字符串返回&#xff0c;同时&#xff0c;nextLine() 会将 Scanner 对象的位置移动到下一行的开头&#xff0c;以便下一次读取数据时从下…

MySQL的约束键多表查询

约束 概念 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。目的&#xff1a;保证数据中数据的正确、有效性和完整性。 外键约束 概念 ​ 外键用来让两张表的数据之间建立连接&#xff0c;从而保证数据的一致性和完整性。 注意&#x…

Qt常用基础控件总结—输入部件(QComboBox类和QLineEdit)

输入部件 下拉列表控件QComboBox 类 QComboBox 类是 QWidget 类的直接子类,该类实现了一个下拉列表(组合框)。 QComboBox 类中的属性函数 1)count:const int 访问函数:int count() const; 获取组合框中的项目数量,默认情况下,对于空组合框或未设置当前项目的组合框,…

c语言的简易教法—— 函数递归

文章目录 一、什么是递归&#xff1f;1.1递归的思想1.2递归的限制条件 二、递归案例2.1 案例1&#xff1a;求n的阶层2.1.1分析2.1.2 递归函数&#xff08;Fact&#xff09;的代码实现2.1.3 测试&#xff1a;main函数实现2.1.4 运行结果和画图推演2.1.5 扩展&#xff1a;迭代方法…

华为如何做成数字化转型?

目录 企业数字化转型是什么&#xff1f; 华为如何定义数字化转型&#xff1f; 为什么做数字化转型&#xff1f; 怎么做数字化转型&#xff1f; 华为IPD的最佳实践之“金蝶云” 企业数字化转型是什么&#xff1f; 先看一下案例&#xff0c;华为经历了多次战略转型&#xf…

前端工程化:Webpack配置全攻略

前端工程化&#xff1a;Webpack配置全攻略 前端小伙伴们&#xff0c;今天我们来聊聊那个让人又爱又恨的 Webpack。没错&#xff0c;就是那个配置起来让你想砸键盘&#xff0c;但又离不开它的构建工具。别担心&#xff0c;跟着我来&#xff0c;保证让你从 Webpack 小白变成配置…

Windows 虚拟机服务器项目部署

目录 一、部署JDK下载JDK安装JDK1.双击 jdk.exe 安装程序2.点击【下一步】3.默认安装位置&#xff0c;点击【下一步】4.等待提取安装程序5.默认安装位置&#xff0c;点击【下一步】6.等待安装7.安装成功&#xff0c;点击【关闭】 二、部署TomcatTomcat主要特点包括&#xff1a;…

感应触摸芯片集成为MCU,深度应用触控按键技术的VR眼镜

VR&#xff08;Virtual Reality&#xff09;即虚拟现实&#xff0c;简称VR&#xff0c;其具体内涵是综合利用计算机图形系统和各种现实及控制等接口设备&#xff0c;在计算机上生成的、可交互的三维环境中提供沉浸感觉的技术。它的工作原理是将左右眼图像交互显示在屏幕上的方式…

技术速递|宣布为 .NET 升级助手提供第三方 API 和包映射支持

作者&#xff1a;Marco Goertz 排版&#xff1a;Alan Wang .NET 升级助手是一个 Visual Studio 扩展和命令行工具&#xff0c;可帮助您将应用从之前的 .NET 和 .NET Framework 升级到最新版本的 .NET。正如我们在之前的文章中所描述的那样&#xff0c;它为升级 Microsoft 库和框…

【C语言】 —— 预处理详解(下)

【C语言】 —— 预处理详解&#xff08;下&#xff09; 前言七、# 和 \##7.1 # 运算符7.2 ## 运算符 八、命名约定九、# u n d e f undef undef十、命令行定义十一、条件编译11.1、单分支的条件编译11.2、多分支的条件编译11.3、判断是否被定义11.4、嵌套指令 十二、头文件的包…

Day1每日编程题日记:数字统计、两个数组的交集、点击消除

前言&#xff1a;该篇用于记录自看。曾回看昨天的做题代码&#xff0c;竟然会觉得陌生&#xff0c;这竟然是我写的&#xff0c;细细读了一下&#xff0c;原来我当时是这么想的。因此我觉得记代码没有实际用处&#xff0c;重点是领悟了思想&#xff0c;这样子代码就在心中&#…