QT开发实战-动态壁纸软件
动态壁纸软件开发
项目源代码在下面链接获取:
-----------------------------
开发者:CodeSharkSJ
希望此项目能加强你对Qt的应用
文章目录
- 项目图与开发环境
- 核心技术原理
- 自定义窗口程序
- UI布局
- 背景绘制
- 样式表
- 基本实现
- QWebEngine
- QMedia使用
- 系统托盘隐藏
- 记忆功能
- 应用程序打包
项目图与开发环境
开发环境: visual studio 2022 + Qt 5.14.1
项目图解:
核心技术原理
桌面图标后面有一个背景窗体,这个窗体没有名字,但是类型属于workerW
它的父类是Program Maneger,
遍历所有workerW类型的窗体,逐一比较它的父窗体是不是Program Manager就可以找到背景窗体。 但如果没有找到可以发送消息生成一个生成一个WorkerW窗体,设置为Program Manager的儿子,再在此上面播放视频。
自定义窗口程序
打开VS2022创建 [ Qt Widgets Application ]
这里Base Class(基类)你必须选择Qwidget
立即编译运行 ,能正常运行就开始下面步骤 。
鼠标无法拖动窗口
您需要添加额外的代码
1.在头文件添加两个继承的方法和一个私有的数据成员
#include <qevent.h>protected:void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);
private:QPoint _Point;
2.实现
mousePressEvent // 鼠标按下事件
void Wallpaper::mousePressEvent(QMouseEvent* event)
{_Point = event->globalPos() - this->pos();
}
mouseMoveEvent // 鼠标移动事件
void Wallpaper::mouseMoveEvent(QMouseEvent* event)
{move(event->globalPos() - _Point);
}
UI布局
打开
右上角皮肤,设置,最小化 ,关闭
图标文件自行准备,在属性栏添加。
我会把项目发给你们🥝🥝
刷新率选择
60HZ设置固定(因为暂时没有120的方案)
调节音量
设置步长1,旁边是标签 设置为0
------------------------
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>WallpaperClass</class><widget class="QWidget" name="WallpaperClass"><property name="geometry"><rect><x>0</x><y>0</y><width>1370</width><height>827</height></rect></property><property name="windowTitle"><string>Wallpaper</string></property><property name="windowIcon"><iconset resource="Wallpaper.qrc"><normaloff>:/Wallpaper/ico/Wall.png</normaloff>:/Wallpaper/ico/Wall.png</iconset></property><property name="styleSheet"><string notr="true"/></property><widget class="Line" name="line"><property name="geometry"><rect><x>0</x><y>40</y><width>1381</width><height>16</height></rect></property><property name="orientation"><enum>Qt::Horizontal</enum></property></widget><widget class="QLabel" name="label"><property name="geometry"><rect><x>10</x><y>10</y><width>131</width><height>21</height></rect></property><property name="palette"><palette><active><colorrole role="WindowText"><brush brushstyle="SolidPattern"><color alpha="255"><red>255</red><green>255</green><blue>255</blue></color></brush></colorrole></active><inactive><colorrole role="WindowText"><brush brushstyle="SolidPattern"><color alpha="255"><red>255</red><green>255</green><blue>255</blue></color></brush></colorrole></inactive><disabled><colorrole role="WindowText"><brush brushstyle="SolidPattern"><color alpha="255"><red>120</red><green>120</green><blue>120</blue></color></brush></colorrole></disabled></palette></property><property name="font"><font><family>微软雅黑</family><pointsize>12</pointsize></font></property><property name="text"><string>Wallpaper</string></property></widget><widget class="QPushButton" name="closeBtn"><property name="geometry"><rect><x>1325</x><y>13</y><width>33</width><height>29</height></rect></property><property name="styleSheet"><string notr="true">QPushButton#closeBtn:hover{
background-color: rgb(219, 0, 0);
color: rgb(255, 255, 255);
border-radius: 1px;
}</string></property><property name="text"><string/></property><property name="icon"><iconset resource="Wallpaper.qrc"><normaloff>:/Wallpaper/MS/CLOSE.png</normaloff>:/Wallpaper/MS/CLOSE.png</iconset></property><property name="iconSize"><size><width>20</width><height>20</height></size></property><property name="flat"><bool>true</bool></property></widget><widget class="QPushButton" name="SkinBtn"><property name="geometry"><rect><x>1200</x><y>11</y><width>37</width><height>33</height></rect></property><property name="toolTip"><string>更换主题</string></property><property name="statusTip"><string/></property><property name="styleSheet"><string notr="true">QPushButton#SkinBtn:hover{
background-color: rgb(90, 90,90);
color: rgb(255, 255, 255);
border-radius: 1px;
}</string></property><property name="text"><string/></property><property name="icon"><iconset resource="Wallpaper.qrc"><normaloff>:/Wallpaper/MS/theme.png</normaloff>:/Wallpaper/MS/theme.png</iconset></property><property name="iconSize"><size><width>24</width><height>24</height></size></property><property name="flat"><bool>true</bool></property></widget><widget class="QPushButton" name="setBtn"><property name="geometry"><rect><x>1243</x><y>11</y><width>37</width><height>33</height></rect></property><property name="toolTip"><string>更多选项</string></property><property name="statusTip"><string/></property><property name="styleSheet"><string notr="true">QPushButton#setBtn:hover{
background-color: rgb(90, 90,90);
color: rgb(255, 255, 255);
border-radius: 1px;
}</string></property><property name="text"><string/></property><property name="icon">...
背景绘制
默认为黑色,点换肤按钮更换
QString tempBg = ConfigFile->value("ckbg").toString(); // 启动程序看配置文件里的背景文件名if (tempBg != "") // 有就设置{startBg(tempBg);}else {QPalette pal;pal.setColor(QPalette::Background, QColor(46, 46, 46));this->setPalette(pal);}void Wallpaper::startBg(QString file)
{QPalette pal = this->palette();pal.setBrush(QPalette::Background, QBrush(QPixmap(file)));setPalette(pal);
}void Wallpaper::onSkinBtn()
{QString tempFile = QFileDialog::getOpenFileName(this, "选择图片", "", "src(*.jpg *.png *.jpeg)"); // 选择背景图ConfigFile->setValue("ckbg", tempFile); // 写到tempFile下次启动就加载 inistartBg(tempFile); // 设置背景的函数
}
样式表
qss(样式表)参考了css 但是并不能像css那样炫酷。
为按钮添加样式表:
关闭:
QPushButton#closeBtn:hover{ #鼠标浮在上面的效果
background-color: rgb (219, 0, 0);
color: rgb(255, 255, 255);
border-radius: 1px;
}
最小化:
QPushButton#minBtn:hover{
background-color: rgb(90, 90,90);
color: rgb(255, 255, 255);
border-radius: 1px;
}
设置:
QPushButton#setBtn:hover{
background-color: rgb(90, 90,90);
color: rgb(255, 255, 255);
border-radius: 1px;
}
改一下颜色
color: rgb(149, 149, 149)
拉动条 :
QSlider::groove:horizontal {
border: 0px solid #bbb;
}QSlider::sub-page:horizontal {background: rgb(90,49,255);border-radius: 2px;margin-top:8px;margin-bottom:8px;}QSlider::add-page:horizontal {background: rgb(255,255, 255);
border: 0px solid #777;
border-radius: 2px;
margin-top:9px;margin-bottom:9px;
}QSlider::handle:horizontal {
background: rgb(193,204,208)
width: 5px;
border: 1px solid rgb(193,204,208);
border-radius: 2px;
margin-top:6px;
margin-bottom:6px;
}QSlider::handle:horizontal:hover {background: rgb(193,204,208);
width: 10px;
border: 1px solid rgb(193,204,208);
border-radius: 5px;
margin-top:4px;margin-bottom:4px;
}
基本实现
😎右上角按钮实现
头文件添加槽,在构造函数内进行信号连接。
private slots:void onCloseBtn();void onMinBtn();void onSetBtn();void onSkinBtn();
构造函数内添加
connect(ui.closeBtn,SIGNAL(clicked()),this,SLOT(onCloseBtn()));connect(ui.minBtn, SIGNAL(clicked()), this, SLOT(onMinBtn()));connect(ui.setBtn, SIGNAL(clicked()), this, SLOT(onSetBtn()));connect(ui.SkinBtn, SIGNAL(clicked()), this, SLOT(onSkinBtn()));
🍉closeBtn:
void Wallpaper::onCloseBtn()
{hide(); // 隐藏用于托盘显示//close();
}
🍎onMinBtn{ showMinimized(); }
🥰onSetBtn { /* 暂不实现 */ }
🍰onSkinBtn // 换肤
QString tempFile = QFileDialog::getOpenFileName(this, "选择图片", "", "src(*.jpg *.png *.jpeg)"); // user选择背景图 ConfigFile->setValue("ckbg", tempFile); // 写 到tempFile下次启动就加载startBg(tempFile); // 设置背景的函数
🍊隐藏到托盘
使用#include <qsystemtrayicon.h> 实现
定义数据成员 在头文件 QSystemTrayIcon* systemtrayicon;
由于有大量的弹出菜单,我们把弹出菜单的需要的东西封在initSpecific()
void Wallpaper::initSpecific()
{systemtrayicon = new QSystemTrayIcon(QIcon(":/Wallpaper/ico/Wall.png"));systemtrayicon->setToolTip(("动态壁纸:运行中"));systemtrayicon->show();QMenu* tray_Menu = new QMenu(this);/*托盘弹出的菜单*/QAction* action1 = new QAction("显示主界面"); QAction* action2 = new QAction("退出壁纸");tray_Menu->setStyleSheet("background-color: rgb(92,92,92);");tray_Menu->addAction(action1);tray_Menu->addSeparator();tray_Menu->addAction(action2);systemtrayicon->setContextMenu(tray_Menu); // 放入connect(action1, SIGNAL(triggered(bool)), this, SLOT(onAction1())); // 注意信号connect(action2, SIGNAL(triggered(bool)), this, SLOT(onAction2()));
}
🥰主界面切换
三个按钮
三按钮槽函数
private slots:void onInstalledBtn();void onDiscovBtn();void onMoberBtn();
void Wallpaper::onInstalledBtn()
{ui.stackedWidget->setCurrentIndex(0);
}void Wallpaper::onDiscovBtn()
{ui.stackedWidget->setCurrentIndex(1);
}void Wallpaper::onMoberBtn()
{ui.stackedWidget->setCurrentIndex(2);
}// 默认在你设计后停留的页面
🥩拉动条
void Wallpaper::onSliderSetNum(int num)
{ui.valuseShow->setText(QString::number(num)); //拉动了就设置旁边的标签mediaPlayer->setVolume(num); // 根据标签设置音量 这个mediaPlayer后面会写}connect(ui.vloueQSlider, SIGNAL(valueChanged(int)), SLOT(onSliderSetNum(int))); // 当进度条拉动 valueChanged发射信号
QWebEngine使用
显示网页
#include <QWebEngineView>// 网址
ui.webEngineView->load(QUrl("https://www.pgyer.com/0uTR"));
把这个放在界面上
QMedia使用
#include <QMediaPlayer>
#include <QMediaPlaylist> // 播放列表 用于循环播放
#include <QVideoWidget> // 播放视频的窗口QVideoWidget* videoWidget;QMediaPlayer* mediaPlayer;QMediaPlaylist* Videolist;Videolist = new QMediaPlaylist;
mediaPlayer = new QMediaPlayer;
videoWidget = new QVideoWidget;
谈一谈这个按钮,按下后选择视频,并在桌面显示出来😎
先来个查找的工具,用于杀死视频窗口,不然释放
QVideoWidget还是会播放。
工具:
#include <Windows.h>//获取背景窗体句柄
HWND GetBackground() {//背景窗体没有窗体名,但是知道它的类名是workerW,且有父窗体Program Maneger,所以只要//遍历所有workerW类型的窗体,逐一比较它的父窗体是不是Program Manager就可以找到背景窗体HWND hwnd = FindWindowA("progman", "Program Manager");HWND worker = NULL;do {worker = FindWindowExA(NULL, worker, "workerW", NULL); // 根据类名获取窗体句柄if (worker != NULL) {char buff[200] = { 0 };int ret = GetClassNameA(worker, (PCHAR)buff, sizeof(buff) * 2);if (ret == 0) {return NULL;}}if (GetParent(worker) == hwnd) {return worker;//返回结果}} while (worker != NULL);//没有找到//发送消息生成一个WorkerW窗体SendMessage(hwnd, 0x052C, 0, 0);//重复上面步骤do {worker = FindWindowExA(NULL, worker, "workerW", NULL);if (worker != NULL) {char buff[200] = { 0 };int ret = GetClassNameA(worker, (PCHAR)buff, sizeof(buff) * 2);if (ret == 0) {return NULL;}}if (GetParent(worker) == hwnd) {return worker;//返回结果}} while (worker != NULL);return NULL;
}void SetBackground(HWND child) {SetParent(child, GetBackground()); // 把视频窗口设置为Program Manager的儿子
}
🤪按钮的实现
void onGetVideo(); // 槽connect(ui.getVideo, SIGNAL(clicked()), this, SLOT(onGetVideo())); void Wallpaper::onGetVideo()
{ if (isPlay == false) // 判断是否有过视频窗口 {QString file;file = QFileDialog::getOpenFileName(this, "选择图片或视频", "", "src(*.mp4)");ConfigFile->setValue("videos", file); // 写入配置文件isPlay = true; // 现在有了showVoide(file); // 放视频具体操作}else{// 不创建窗口模式 直接设置播放列表里面的视频mediaPlayer->stop();QString file;file = QFileDialog::getOpenFileName(this, "选择图片或视频", "", "src(*.mp4)");ConfigFile->setValue("videos", file);NextVideo(file); // 启动下一个视频}return;
}
showVoide
void Wallpaper::showVoide(QString Name)
{HWND hwnd = (HWND)videoWidget->winId(); //获取播放视频的窗口idSetBackground(hwnd);videoWidget->setWindowFlags(Qt::FramelessWindowHint); // // 隐藏标题栏videoWidget->showFullScreen(); // 最大化显示
/*this->windowClose = tempWork; //获取子窗口id后面用来关闭2023年1月29日21:30:01 发现bug 这段代码是直接关了系统背景资源管理器会崩溃
*/ this->windowClose = hwnd; // 到时候直接杀播放视频的窗口就行了 但会留下壁纸// mediaPlayer为播放控制器 用于启动播放 Videolist是播放列表Videolist->addMedia(QMediaContent(QUrl::fromLocalFile(Name)));// 设置要播放的文件路径Videolist->setCurrentIndex(0);Videolist->setPlaybackMode(QMediaPlaylist::Loop); // 循环mediaPlayer->setVideoOutput(videoWidget); // 设置视频输出窗口mediaPlayer->setPlaylist(Videolist);mediaPlayer->play();
}
NextVideo
void Wallpaper::NextVideo(QString Name)
{Videolist->clear();Videolist->addMedia(QMediaContent(QUrl::fromLocalFile(Name)));mediaPlayer->play();
}
记忆功能
程序启动时检查配置文件,进行响应的调度 。
QSettings可以提供方便的ini配置操作
#include <QSettings>QString GetAPPDATAFolder()
{wchar_t path[255] = { 0 };SHGetSpecialFolderPath(NULL, path, CSIDL_APPDATA, FALSE );QString rlt = QString::fromWCharArray(path);return rlt;
}QString folder = GetDesktopFolder(); //获取用户数据文件夹 一般配置文件放里面
folder.append("\\Wallpaper_user.ini");ConfigFile = new QSettings(folder, QSettings::IniFormat);
ConfigFile->beginGroup("USERRCONFIG"); // 节点名QString tempBg = ConfigFile->value("ckbg").toString(); // 读这个ckbg下的数据
// ConfigFile->setValue("ckbg", tempFile); // 写// 加载上次设置的视频QString tempVid = ConfigFile->value("videos").toString();if (tempVid != ""){if (isPlay == false){isPlay = true;showVoide(tempVid);}}
应用程序打包
如何在让程序在别的计算机执行
一、使用这个工具
找不到用Everything 搜。
选Release 和 x64 编译
打开终端程序,进入程序所在目录
输入
windeployqt D:\local\Wallpaper.exe
会自动加载所需。
二、Enigma Virtual Box
虚拟目录
使一些dll和其他文件隐藏,只有exe程序。
---------------------------------------------------------
由于没有使用MD编辑文章,观感可能不舒服,请见谅。
有问题私信
------------------------------------------------------------
源代码:
链接:https://pan.baidu.com/s/1-HUPkdniFPPHUJ2B8AC0wQ?pwd=sjfd
提取码:sjfd
相关文章:

QT开发实战-动态壁纸软件
动态壁纸软件开发 项目源代码在下面链接获取: ----------------------------- 开发者:CodeSharkSJ 希望此项目能加强你对Qt的应用 文章目录 项目图与开发环境核心技术原理自定义窗口程序UI布局背景绘制样式表基本实现QWebEngineQMedia使用系统托盘隐藏记忆功能应用程序打包 …...
Netty核心组件模块(一)
1.Bootstrap和ServerBootstrap 1>.Bootstrap意思是引导,一个Netty应用通常由一个Bootstrap开始,主要作用是配置整个Netty程序,串联各个组件,Netty中Bootstrap类是客户端程序的启动引导类,ServerBootstrap是服务端启动引导类; 2>.常见的方法有: ①.public ServerBootstr…...

Robot Framework+Jenkins持续集成UI自动化项目
使用Robot Framework框架可进行Web端和APP端的UI自动化测试,为方便定时执行,可将Robot Framework的自动化项目持续集成至Jenkins平台,具体的操作步骤如下: 安装Jenkins的步骤如下: 手把手教小白安装Jenkins_程序员馨馨…...

【ROS】ROS1编程速览
1、简述 很多项目已经转向ROS2,本人作为ROS小白从ROS1开始学起,但是不会深入学习ROS1,只一带而过。 下面只了解一些ROS1中的概念和基本编程接口。 ROS1中有两种通信模式:话题模式和服务模式,区别如下 2、话题模式 …...

探索智能化:TOOM解析未来稿件校验系统的技术进展与应用展望
在信息时代,随着大数据、人工智能和自然语言处理等技术的快速发展,稿件校验系统正朝着智能化的方向迈进。智能化的稿件校验系统能够更准确、高效地检测虚假信息、抄袭行为以及提升文章质量。本文将探讨智能化稿件校验系统的技术进展与应用展望࿰…...
Java程序员从青铜到王者,不同段位的薪资和技能变化
想要薪资高,段位就得跟上,对于Java程序员来说,从青铜到王者,需要经历多个阶段,每个阶段需要掌握的技能都不一样。 今天,我们一起来看看每个段位都有什么特点、需要具备哪些“大杀”技能,也看看…...

tinyWebServer 学习笔记——二、HTTP 连接处理
文章目录 一、基础知识1. epoll2. 再谈 I/O 复用3. 触发模式和 EPOLLONESHOT4. HTTP 报文5. HTTP 状态码6. 有限状态机7. 主从状态机8. HTTP_CODE9. HTTP 处理流程 二、代码解析1. HTTP 类2. 读取客户数据2. epoll 事件相关3. 接收 HTTP 请求4. HTTP 报文解析5. HTTP 请求响应 …...

深入浅析Linux Perf 性能分析工具及火焰图
Perf Event 子系统 Perf 是内置于 Linux 内核源码树中的性能剖析(profiling)工具。它基于事件采样的原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。可用于性能瓶颈的查找与热点代码的定位…...
java关键术语
java具有11个关键的术语,这些术语是从java的设计者所编写的白皮书中摘取,这些术语分别为:简单性、面向对象、分布式、健壮性、安全性、体系结构中立、可移植性、解释型、高性能、多线程、多态性。以下开始我们将逐一解说这些术语。 一、简单性 Java是C++语法的纯净版本,剔…...
1. 两数之和【简单】
题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺…...

《编码——隐匿在计算机软硬件背后的语言》精炼——第17章(自动操作)
夫道成于学而藏于书,学进于振而废于穷。 文章目录 完善加法器加入代码的加法器扩大加数范围自由调用地址的加法器合并代码RAM和数据RAMJump指令硬件实现条件Jump指令零转移的硬件实现条件Jump指令的例子 总结 完善加法器 我们在第14章介绍了一个可以进行连加的加法…...

用Colab免费部署AI绘画云平台Stable Diffusion webUI
Google Colab 版的 Stable Diffusion WebUI 1.4 webui github 地址:https://github.com/sd-webui/stable-diffusion-webui 平台搭建 今天就来交大家如果来搭建和使用这个云平台。 第一步: 打开链接 https://colab.research.google.com/github/altryne/sd-webu…...

R.I.P,又一位程序员巨佬——左耳朵耗子陨落
震惊!谣言吧!求辟谣!默哀! 左耳朵耗子,在程序员这个群体里应该属于 GOAT 的存在了,虽然每个人心目中都有自己的 GOAT,但耗子叔的影响力可以说是有目共睹。 我也是在技术群刷到这张图片的&#…...

捷威信keithley吉时利2410数字源表 销售回收KEITHLEY2470新款源表
吉时利Keithley 2410 /2470高压源表/数字源表 产品概览 Keithley 2410 高压源表专为需要紧密耦合源和测量的测试应用而设计。Keithly 2410 提供精密电压和电流源以及测量功能。它既是高度稳定的直流电源,又是真正的仪器级 5-1/2 数字万用表。电源特性包括低噪声、…...
第二十九回:如何给ListView添加分隔线
文章目录 概念介绍添加方法使用属性装饰器 示例代码经验总结: 我们在上一章回中介绍了多种创建ListView的方式,本章回中将介绍" 如何给ListView添加分隔线".闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里说的分隔线也叫Divider,…...
用友 LRP计划维护视图
select planlotnumber 计划单号, demandId 自动编号, PartId 物料Id , sotype 单据类型(1:销售/2:预测), sodid 销售订单明细Id , socode 销售订单单号 , soseq 销售订单行号, PlanCode 计划单号 , DueDate 完工日期 , StartDate 开工日期 , UnitCode 主计量单位, C…...

数组--part 5--螺旋矩阵(力扣59/54)(剑指offer 29)
文章目录 基本算法思想leetcode 59 螺旋矩阵 IIleetcode 54 螺旋矩阵剑指Offer 29 顺时针打印矩阵 基本算法思想 建议先去把题目看了,再来思考相关的代码。 错误的想法:实际上这种题型并不存在算法,只涉及到模拟,但是模拟难度并…...

加密解密软件VMProtect入门使用教程(九)许可制度之许可系统功能
VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic(本机)、Virtual Pascal和XCode编译器。 同时,VMProtect有一个内置的反汇编程序,可以与Windows和Mac OS X可执行文件一起…...

MySQL基础-事务详解
本文主要介绍MySQL事务 文章目录 前言事务定义事务四大特性(ACID) 事务操作事务并发问题事务隔离级别 前言 参考链接: 链接1链接2 事务定义 事务是一组操作的集合,他是一个不可分割的工作单位,事务会把所有的操作作…...

python 读写csv文件方法
csv是一种结构化文件,可以将文本转化成矩阵的形式,方便程序读取和处理。下面来介绍一下使用 python读写 csv文件的方法: 1.首先需要使用 pip安装 python包,然后将 csv文件解压到一个文件夹下 2.使用 pip安装 python包,…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...

五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...