HarmonyOS应用开发(组件库)--组件模块化开发、工具包、设计模式(持续更新)
致力于,UI开发拿来即用,提高开发效率
- 常量格式
- 枚举enum格式
- 正则表达式
- ...手机号校验
- ...邮箱校验
- 文件
- 判断文件是否存在
- 网络下载
- 下载图片
- 从沙箱中图片转为Base64格式
- 从资源文件中读取图片转Base64
- 组件
- 输入框
- ...矩形输入框
- ...输入框堆叠效果(用于登录使用)
- 文本
- ...Text公用组件:TextView
- 按钮
- ...Button公用组件:ButtonView
- ...单选按钮公用组件:RadioView
- 组件工具包
- ...输入框(矩形)
- ...登录延时效果
- ...UI分页查询的实现
- ...弹框和短通知工具包
- 成形UI
- ...聊天界面UI
- 类、接口、枚举工具包
- 进程间通讯(IPC)
- 设计模式
- 单例模式

常量格式
export class CommonConstants {// 首选项名称static readonly PRE_USER:string= "user"// 全局应用static readonly STORE_USER:string= "user"// 列表查询行数static readonly LIST_SIZE:number = 10
}
枚举enum格式
// 数值可以为number、string
export enum Status {Enable=0, //启用Disable=1 // 禁用
}
正则表达式
…手机号校验
isValidPhoneNumber(phoneNumber: string): boolean {const regex = /^(13[0-9]|14[5|7|9]|15[0-3|5-9]|16[2|5|6|7]|17[0-8]|18[0-9]|19[8|9])\d{8}$/;return regex.test(phoneNumber)}
…邮箱校验
isValidEmail(email: string): boolean {let regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;return regEmail.test(email)}
文件
导包: import fs from ‘@ohos.file.fs’;
判断文件是否存在
// 判断文件是否存在?let imgFile = filesDir + '/myImg.png'; // 路径let res = fs.accessSync(imgFile);if (res) {//如存在,就删除fs.unlinkSync(imgFile);}
网络下载
导包:
import request from ‘@ohos.request’;
import fs from ‘@ohos.file.fs’;
下载图片
request.downloadFile(getContext(), {url: netFile, filePath: imgFile // 网络路径,本地路径}).then((task) => {task.on('complete', function callback() {let file:fileIo.File;file = fs.openSync(imgFile) // 本地路径prompt.showToast({message: "文件下载成功:" + imgFile})})task.on('fail', function callBack(err) {prompt.showToast({message: "文件下载失败,err:" + JSON.stringify(err)})});
从沙箱中图片转为Base64格式
// 工具包:
// 其中当转为这个后,可能会与原文件有差异,需要修改配置base64ImgStr
// 获取沙箱路径:this.context.__Dir
async toBase64(image_uri: string) {if (image_uri) {let selectImage = fs.openSync(image_uri, fs.OpenMode.READ_WRITE) // openSync() 根据文件file://路径 转文件const imageSource = image.createImageSource(selectImage.fd);const imagePackerApi: image.ImagePacker = image.createImagePacker();let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 100 };let readBuffer = await imagePackerApi.packing(imageSource, packOpts);let bufferArr = new Uint8Array(readBuffer)let help = new util.Base64Helperlet base = help.encodeToStringSync(bufferArr)let base64ImgStr = 'data:image/png;base64,' + base; // 回显需要有前面的前缀才可以return base64ImgStr;}return '';
}
从资源文件中读取图片转Base64
async toBase64StrFromResource(img_name: string) {// 1. 获取图片所对应的PixelMap对象let pixelMap: PixelMap = await this.toPixelMapFromResource(img_name); // 自己封装函数,见下// 2. 获取pixelMap总字节数let pixelBytesNumber: number = pixelMap.getPixelBytesNumber();// 3. 创建了一个ImagePacker对象,用于图像编码。(ImagePacker是HarmonyOS中用于将图像(PixelMap格式)编码为不同存档格式的工具)const imagePackageApi: image.ImagePacker = image.createImagePacker();// 4. 定义了一个PackingOption对象,用于设置图像编码的选项。let packOpts: image.PackingOption = {format: 'image/jpeg', //表示编码的图像格式为jpeg格式quality: 100, //表示图像质量为最高质量(取值为0~100之间)}// 5. 将pixelMap对象按照packOpts中设置的选项进行编码。编码的结果被存储在readBuffer中const readBuffer = await imagePackageApi.packing(pixelMap, packOpts);// 6. 创建了一个Base64Helper对象,用于进行Base64编码和解码操作。let base64Helper = new util.Base64Helper();// 7. 将readBuffer转换为一个Uint8Array对象(Uint8Array是一种JavaScript内置对象,表示一个8位无符号整数的数组,适合表示二进制数据。)let uint8Arr = new Uint8Array(readBuffer);// 8. 将uint8Arr中的二进制数据同步地编码为Base64字符串let pixelStr = base64Helper.encodeToStringSync(uint8Arr);// 9. 加入base64编码协议(用于显示在Image组件中)(以下前缀形成一个可以在Web上直接使用的Data URL。这个Data URL可以被用于在HTML或CSS中嵌入图像数据,而不需要额外的图像文件)let base64ImgStr = 'data:image/png;base64,' + pixelStr;Log.MyLog("'hmlog-->',base64 str : " + base64ImgStr);// 10. 返回编码后并转换为Data URL的Base64字符中return base64ImgStr;}async toPixelMapFromResource(img_name: string) {// 1. 获取stage模型下的Context上下文对象const context = getContext(this);// 2. 获取ResourceManager资源管理类const resourceMgr = context.resourceManager;// 3. 获取resource/rawfile/face.pngconst fileData = await resourceMgr.getRawFileContent(img_name)// 4. 获取图片的ArrayBufferconst buffer = fileData.buffer;// 5. 创建ImageSource实例const imageSource = image.createImageSource(buffer);// 6. 定义解码参数DecodingOptionslet decodingOptions = {editable: true, // editable设置为true表示图片是可编辑的desiredPixelFormat: 3 // desiredPixelFormat设置为3表示解码的像素格式为RGBA_8888}// 7. 根据解码参数DecodingOptions获取PixelMap图片对象const pixelMap = await imageSource.createPixelMap(decodingOptions)// 8. 返回PixelMap图片对象return pixelMap;}
组件
(图片样式+代码) : 封装的组件则放在工具包下,可以使用 CTRL+F进行搜索 如: TextInputRectangleView
输入框
…矩形输入框
若有其他变动,可以修改参数即可
TextInputRectangleView({placeholder: '请输入手机号/邮箱',onClickCallBack: (value: string) => { // 回调函数this.name = value}})
…输入框堆叠效果(用于登录使用)
Stack({ alignContent: Alignment.End }) { // 布局TextInputRectangleView({placeholder: '请输入验证码',inPutType: InputType.Number,onClickCallBack: (value: string) => {this.code = value}})Text(this.message).fontColor(Color.Red).padding({ right: 20 }).enabled(this.isEnable).opacity(this.isEnable ? 1 : 0.5).onClick(() => {// 点击字体时的业务处理this.wait() // 延时this.getVaCode() // 校验代码})}.width("100%")// 延时函数点击重新获取触发wait() {let time = 60let id = setInterval(() => {time--this.isEnable = false // 禁用的状态this.message = '重新获取(' + time + ")s"if (time <= 0) {this.isEnable = truethis.message = '重新获取'}}, 1 * 1000)}
文本
…Text公用组件:TextView
@Component
export default struct TextView {text:ResourceStr|number= ''fontColor:ResourceStr|Color = Color.BlackfontSize:ResourceStr|number = 16fontWeight:number | FontWeight | string = FontWeight.NormalbackgroundColor2:ResourceColor = Color.Whitedecoration:TextDecorationType= TextDecorationType.NoneonClickCallBack ?:()=>void=()=>{} // 设置默认否则会导致,使用组件不调用导致闪退build() {Row(){Text(''+this.text).fontColor(this.fontColor).fontSize(this.fontSize).fontWeight(this.fontWeight).decoration({ type: this.decoration}).backgroundColor(this.backgroundColor2).onClick(()=>{this.onClickCallBack()})}}
}
使用方式:
例:
TextView({text: "详细信息",fontColor: "#ff2a24e5",fontSize: 25,fontWeight: FontWeight.Bold,})
按钮
…Button公用组件:ButtonView
@Component
export default struct ButtonView {text:ResourceStrcomWidth:number|string|Resource = "100%"comHeight:number|string|Resource = 50onClickCallback ?:()=>void=()=>{} // 回调函数type:ButtonType =ButtonType.Capsule // 默认胶囊backgroundColor2:ResourceColor = Color.BlueisEnabled:boolean = true // 启用build() {Column(){Button(this.text,{type:this.type}).width(this.comWidth).height(this.comHeight).onClick(()=>{this.onClickCallback()}).backgroundColor(this.backgroundColor2).enabled(this.isEnabled)}}
}
使用方式:
例:
ButtonView({text: "修改",comWidth: 50,comHeight: 30,backgroundColor2: item.getUserType() === UserType.Admin ? Color.Grey : "#ff0f9107",type: ButtonType.Normal,isEnabled: item.getUserType() === UserType.Admin ? false : true,onClickCallback: () => {this.changUserState(Operate.UpdateUser, item)}})
…单选按钮公用组件:RadioView
import { Status } from '../entity/User'
@Component
export default struct RadioView {group:string='group'text: stringradiosValue: Array<number>radiosStr: Array<string>checked: number = -1onClickCallBack ?:(value?:number)=>void=()=>{}isEnabled:Status = Status.Enablebuild() {Row({ space: 10 }) {if (this.text) {Text(this.text+':')}ForEach(this.radiosValue, (item: number, index: number) => {Row(){Radio({ value: item.toString(), group: this.group }) // 枚举值.onClick(() => {this.onClickCallBack(item)}).checked(this.checked == item).enabled(!this.isEnabled) // false: 禁用Text(this.radiosStr[index]) // 对应的文本}.margin({right:10}).width("80")})}}
}
使用方式:(需要自己定义枚举)
例:
Row() {RadioView({group: 'sex',text: '性别',isEnabled: Status.Enable,radiosValue: [UserSex.Girl, UserSex.Boy],radiosStr: ['女', '男'],onClickCallBack: (val: number) => {this.user.setUserSex(val)}})}.width("100%")
组件工具包
(图片样式+代码) ,结合组件UI进行使用
…输入框(矩形)
@Preview
@Component// 文本输入框矩形
export default struct TextInputRectangleView {text ?: stringplaceholder?: stringinPutType ?: InputType = InputType.NormalonClickCallBack : (value: string) => void = () => { // 回调函数}width2?: ResourceStr | number = "100%"height2?: ResourceStr | number = 50backgroundColor2?: ResourceColor = "#ddd"borderRadius2 ?: number = 10build() {Row() {TextInput({ placeholder: this.placeholder, text: this.text }).type(this.inPutType).onChange((val: string) => {this.onClickCallBack(val)}).backgroundColor(this.backgroundColor2).placeholderColor(Color.Grey) // 提示信息颜色}.width(this.width2).height(this.height2).backgroundColor(this.backgroundColor2).borderRadius(this.borderRadius2)}
}
…登录延时效果
wait() {let time = 60let id = setInterval(() => {time--this.isEnable = false // 禁用的状态this.message = '重新获取(' + time + ")s"if (time <= 0) {this.isEnable = truethis.message = '重新获取'}}, 1 * 1000)}
…UI分页查询的实现
1.UI渲染思路:(定义所需变量)@State page: number = 1 // 默认当前页@State totalPage: number = 1 // 总页数@State size: number = 10 // 显示业务---一般可以定义至常量: static readonly LIST_SIZE:number = 102.初始化数据:根据声明周期,获取数据和查询总数并计算总页数this.totalPage = 数据总数/ 每页显示数量size3.UI和分页按钮的组建: (见例3)4.UI加载页面优化: 为了提升用户体验,应显示加载动画,或者当没有数据时,提示暂无数据: (见例4)5.数据库查询分页公式:需要参数:const sizes = CommonConstants.LIST_SIZE // 每页显示数量const pages = (page - 1) * sizes // 计算查询列表数量在limit时使用格式:select * from tableName where ..... limit pages ,sizes // 从第几个开始,显示多少sizes数量
例: 例3// 数据列表
ForEach(this.list, (item: User, index: number) => {// 仅能创建UIRow() {TextView({ text: item.getAccountName(),fontColor: Color.Blue,onClickCallBack: () => {// 自定义弹框页面// 存放位置目的主要获取item传参this.dialog = new CustomDialogController({// 自定义组件 使用@CustomDialog装饰器 和 controller:CustomDialogControllerbuilder: UserDetailDialog({ item: item }), //自定义组件或者函数,并可以传入想要的值autoCancel: false, // 是否任意点击取消弹出框alignment: DialogAlignment.Center, // 样式cancel: () => {// 自定义弹框页面this.dialog.close()}})// 开启this.dialog.open()}}).layoutWeight(1)TextView({ text: item.getUserType() ? '管理员' : '普通',fontColor: item.getUserType() ? Color.Red : Color.Grey}).layoutWeight(1).align(Alignment.Center)TextView({ text: item.getUserState() ? '正常' : '禁用',fontColor: item.getUserState() ? Color.Grey : Color.Blue }).layoutWeight(1).align(Alignment.Center)Row({ space: 5 }) {ButtonView({text: "删除",comWidth: 50,comHeight: 30,backgroundColor2: item.getUserType() === UserType.Admin ? Color.Grey : "#fff35454",type: ButtonType.Normal,isEnabled: item.getUserType() === UserType.Admin ? false : true,onClickCallback: () => {this.changUserState(Operate.Delete, item)}})ButtonView({text: (item.getUserType() === UserType.Admin) ? '禁用' : ((item.getUserState()) ? '禁用' : '启用'),comWidth: 50,comHeight: 30,backgroundColor2: item.getUserType() === UserType.Admin ? Color.Grey : (item.getUserState() ? "#ffe3da46" : "#ff0b95e0"),type: ButtonType.Normal,isEnabled: item.getUserType() === UserType.Admin ? false : true,onClickCallback: () => {item.setUserState(item.getUserState() ? UserState.Disable : UserState.Enable)this.list[index] = new User() // 保证页面的即使刷新,用户感受this.list[index] = itemthis.changUserState(Operate.Update, item) // 处理业务}})ButtonView({text: "修改",comWidth: 50,comHeight: 30,backgroundColor2: item.getUserType() === UserType.Admin ? Color.Grey : "#ff0f9107",type: ButtonType.Normal,isEnabled: item.getUserType() === UserType.Admin ? false : true,onClickCallback: () => {this.changUserState(Operate.UpdateUser, item)}})}.layoutWeight(2).align(Alignment.Center)}.width("100%").padding({ bottom: 5, top: 5 }).border({ width: { bottom: 1 }, color: { bottom: "#ddd" } })}// ==============================================================================
// 分页UIRow({ space: 30 }) {Row() {Text(`页数: ${this.page}/${this.totalPage}`).fontColor("#ff0b95e0")}.padding({ left: 30 })Row({ space: 10 }) {ButtonView({text: "|<",comWidth: 50,comHeight: 30,backgroundColor2: "#ff0b95e0",type: ButtonType.Normal,onClickCallback: () => {if (this.page != 1) {this.page = 1this.onClickCallBack()}}})ButtonView({text: "<<",comWidth: 50,comHeight: 30,backgroundColor2: "#ff0b95e0",type: ButtonType.Normal,onClickCallback: () => {if (this.page > 1) {this.page--this.onClickCallBack()}}})ButtonView({text: ">>",comWidth: 50,comHeight: 30,backgroundColor2: "#ff0b95e0",type: ButtonType.Normal,onClickCallback: () => {if (this.page < this.totalPage) {this.page++this.onClickCallBack()}}})ButtonView({text: ">|",comWidth: 50,comHeight: 30,backgroundColor2: "#ff0b95e0",type: ButtonType.Normal,onClickCallback: () => {if (this.totalPage != this.page) {this.page = this.totalPagethis.onClickCallBack()}}})}}.padding({ top: 20, right: 20 }).justifyContent(FlexAlign.SpaceBetween).width("100%")
例: 例4
if (this.loading) {// 加载LoadingProgress() // 加载动画.width(50).height(50)Text("数据加载中.....").fontColor("#bbb").margin({top:20})} else if (this.list.length==0){Text("暂无数据").fontColor("#bbb").margin({top:20})} else {// 正常业务处理}
…弹框和短通知工具包
import promptAction from '@ohos.promptAction'
// 短通知
export function showToast(info:string,time:number = 3*1000){promptAction.showToast({message:info,duration:time})
}// 消息弹窗
export function showDialog(msg:string,title:string='系统提示',callback:()=>void=()=>{}){ // callback 赋值的为默认值promptAction.showDialog({title:title,message:msg}).catch(callback)
}// 确认弹框
export function AlterDialog(title:string,message:string,submit:()=>void=()=>{},cancel:()=>void=()=>{}){AlertDialog.show({title:title,message:message,primaryButton:{value:"取消",action:()=>{cancel()}},secondaryButton:{value:'确定',action: () => {submit()}},})
}// log和err日志
export function loggerInfo(str:string){console.info('system===>',str)
}
export function loggerError(str:string){console.error('system===>',str)
}
成形UI
…聊天界面UI
思路:
代码组件
类、接口、枚举工具包
进程间通讯(IPC)
import commonEventManager from '@ohos.commonEventManager'// Publisher通讯事件类型
enum PublishEventType {APP_PUBLISH = "APP_PUBLISH",CARD_PUBLISH = "CARD_PUBLISH"
}class IPCManagerClass {static publishCount:number = 1// 发布者static publish(eventType:PublishEventType,data:string){// commonEventManager作用:可用于进程间通讯commonEventManager.publish(eventType,{data},(err)=>{if(err){// 失败只发3次if(this.publishCount<=3){this.publish(eventType,data)}else{this.publishCount = 1}}else{this.publishCount = 1}})}// 订阅者static subscribe(eventType:PublishEventType,subscriber,callback:(event:string)=>void){commonEventManager.createSubscriber({ events: [eventType] }, (err, data) => {if (err) {return console.log('common-->', `创建订阅者error ${JSON.stringify(err)}`)}console.log('common-->', `创建订阅者success`)subscriber = dataif (subscriber !== null) {//订阅事件commonEventManager.subscribe(subscriber, (err, data) => {if (err) {return console.error(`logData`, '订阅事件失败')}console.log('common-->',`接受订阅事件:${data.data}`)callback(data.data)})} else {console.error('common-->',`需要创建subscriber`);}})}
}export {IPCManagerClass,PublishEventType}
设计模式
单例模式
单例模式分为: 懒汉式和饿汉式,懒汉式常用。
创建步骤:
1.将构造器私有化: private constructor() {} // 可以修改为传参,定义一个私有属性,在new Class时,赋值即可
2.定义私有静态实例,但不创建: private static clsss: Class
3.创建共用的静态函数:
public static initialization():Class{
if(!clsss){
Class.class = new Class() // 不存在是才会创建
//若有参数 Class.class = new Class('参数') // 不存在是才会创建
}
return Class.class
}
相关文章:

HarmonyOS应用开发(组件库)--组件模块化开发、工具包、设计模式(持续更新)
致力于,UI开发拿来即用,提高开发效率 常量格式枚举enum格式正则表达式...手机号校验...邮箱校验 文件判断文件是否存在 网络下载下载图片从沙箱中图片转为Base64格式从资源文件中读取图片转Base64 组件输入框...矩形输入框...输入框堆叠效果(…...

python测试开发---前后端交互Axios
Axios 是一个基于 Promise 的 HTTP 客户端,常用于浏览器和 Node.js 中发送 HTTP 请求。它封装了 XMLHttpRequest 和 Node.js 的 http 模块,使得处理网络请求更加简单和直观,尤其适合处理异步请求。以下是 Axios 的基础概念和使用方法…...

删除视频最后几帧 剪切视频
删除视频最后几帧 剪切视频 remove_last.py import subprocess def remove_last_frame(input_file, output_file, frame_rate):command_duration [ffprobe,-v, error,-show_entries, formatduration,-of, defaultnoprint_wrappers1:nokey1,input_file]try:total_duration fl…...

SSM框架学习(四、SpringMVC实战:构建高效表述层框架)
目录 一、SpringMVC简介和体验 1.介绍 2.主要作用 3.核心组件和调用流程理解 4.快速体验 二、SpringMVC接收数据 1.访问路径设置 (1)精准路径匹配 (2)模糊路径匹配 (3)类和方法上添加 RequestMapp…...

戴尔笔记本电脑——重装系统
说明:我的电脑是戴尔G3笔记本电脑。 第一步:按照正常的装系统步骤,配置并进入U盘的PE系统 如果进入PE系统,一部分的硬盘找不到,解决办法:U盘PE系统——出现部分硬盘找不到的解决办法 第二步:磁…...

领夹麦克风哪个品牌音质最好,主播一般用什么麦克风
在这个信息爆炸的时代,清晰的声音传达显得尤为重要。无论是激情澎湃的演讲,还是温馨动人的访谈,一款优质的无线领夹麦克风都能让声音清晰的传播。但市场上产品繁多,如何挑选出性价比高、性能卓越的无线领夹麦克风呢?本…...

华为静态路由(route-static)
静态路由的组成 在华为路由器中,使用ip route-static命令配置静态路由。 一条静态路由主要包含以下要素: 目的地址:数据包要到达的目标IP地址 子网掩码:用于指定目的地址的网络部分和主机部分 下一跳地址(可选&#…...

Focalboard开源项目管理系统本地Windows部署与远程访问协同办公
文章目录 前言1. 使用Docker本地部署Focalboard1.1 在Windows中安装 Docker1.2 使用Docker部署Focalboard 2. 安装Cpolar内网穿透工具3. 实现公网访问Focalboard4. 固定Focalboard公网地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂&am…...

Java如何操作Elasticsearch
目录 前言 Procuct实体类 一、操作索引 二、操作文档 三、查询文档 四、复杂条件查询 五、分页查询 六、结果排序 本文文章介绍的是通过template的方法操作elasticsearch,他的话直接本地注入使用就行,repository方法还需要实现接口,所…...

cpu路、核、线程、主频、缓存
路:主板插口实际插入的 CPU 个数,也可以理解为主板上支持的CPU的数量。每个CPU插槽可以插入一个物理处理器芯片。例如,一台服务器可能有2路或4路插槽,这意味着它最多可以安装2个或4个物理处理器。 核:单块 CPU 上面能…...

【AI算法岗面试八股面经【超全整理】——深度学习】
AI算法岗面试八股面经【超全整理】 概率论【AI算法岗面试八股面经【超全整理】——概率论】信息论【AI算法岗面试八股面经【超全整理】——信息论】机器学习【AI算法岗面试八股面经【超全整理】——机器学习】深度学习【AI算法岗面试八股面经【超全整理】——深度学习】NLP【A…...

STL——map和set【map和set的介绍和使用】【multimap和multiset】
目录 map和set1.关联式容器2.键值对3.树形结构的关联式容器3.1set3.1.1set的介绍3.1.2set的使用3.1.2.1set的模版参数列表3.1.2.2set的构造3.1.2.3set的迭代器3.1.2.4set基本接口的使用3.1.2.5set使用案例 3.2map3.2.1map介绍3.2.2map的使用3.2.2.1map的构造3.2.2.2map的迭代器…...

【笔记】神领物流配置本地hosts无法访问域名(排除DNS 排除文件编码问题)已解决
第一次看着文档准备项目 踩坑不少 一遇到问题总是想着先自己解决 其实文档里就有解决方法 看文字总是喜欢跳过 导入虚拟机的时候忘记了给它设置ip地址 按照文档来就好了 配置完之后立刻就可以通过域名访问了 以防万一写一个本地hosts文件的路径在这里 通常来说都是ÿ…...

Java | Leetcode Java题解之第424题替换后的最长重复字符
题目: 题解: public class Solution {public int characterReplacement(String s, int k) {int len s.length();if (len < 2) {return len;}char[] charArray s.toCharArray();int left 0;int right 0;int res 0;int maxCount 0;int[] freq n…...

Xcode 16 Pod init 报错
pod init failed in Xcode 16 Issue #12583 CocoaPods/CocoaPods GitHub 根据你提供的步骤,以下是详细的操作指南来解决 CocoaPods 的问题: ### 步骤 1:在 Xcode 中转换项目文件夹为组 1. 打开你的 Xcode 项目。 2. 在左侧的项目导航器…...

【数据结构】Java的HashMap 和 HashSet 大全笔记,写算法用到的时候翻一下,百度都省了!(实践篇)
本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人…...

Docker 教程:如何查看容器的最后 300 行实时日志
Docker 教程:如何查看容器的最后 300 行实时日志 文章目录 Docker 教程:如何查看容器的最后 300 行实时日志Docker 日志简介查看容器日志的基本命令查看最后 300 行实时日志的具体命令参数解释 实际案例演示示例输出 常见问题解答如何退出实时日志的查看…...

Qwen2-VL论文阅读笔记
第1章介绍 论文亮点: 1、 the Naive Dynamic Resolution mechanism 2、Multimodal Rotary Position Embedding (M-RoPE) 2D Rotary Position Embedding 3、统一图片和视频的处理范式、增i强视觉感知能力 4、LVLMs的scaling laws:2B、8B、72B 5、 dynamic…...

APScheduler、Django实现定时任务,以及任务动态操作
环境:Windows 11、python 3.12.3、Django 4.2.11、 APScheduler 3.10.4 背景:工作需要使用且用法较为复杂,各种功能基本都使用了 事件:20240920 说明:记录,方便后期自己查找 1、搭建基础环境 文件结构图…...

SpringBoot开发——整合Apache POI轻松生成精美的Excel报表
文章目录 1、准备工作2、编写代码2.1 创建实体类2.2 创建Excel生成服务2.3 创建控制器 3、测试4、结论 在许多企业应用程序中,导出数据到Excel表格是一项常见的需求。Spring Boot提供了许多库来简化这个过程,其中包括Apache POI和Spring Boot的相关模块。…...

海信智能电视的使用心得
买了海信智能电视(型号:32E2F)有一段时间了,要使用这个智能电视还真能考验你的智商。海信电视有很多优点,它的屏幕比较靓丽,色彩好看,遥控器不用对着屏幕就能操作。但也有不少缺点。 1. 海信智能电视会强迫自动更新操作系统&…...

【YashanDB知识库】客户端字符集与数据库字符集兼容问题
本文转自YashanDB官网,具体内容请见https://www.yashandb.com/newsinfo/7352675.html?templateId1718516 问题现象 客户端yasql配置字符集为GBK,服务端yasdb配置字符集为UTF8,之后执行语句: 会发现: 期望是两个都…...

Session和Cookie是什么?有什么区别?分布式Session问题又是什么?
Session和Cookie是什么?有什么区别?分布式Session问题又是什么? Cookie:是服务器发送到浏览器并保存在本地的数据。在浏览器下一次向同一服务器再次发送请求时,将Cookie也发送给服务器,并以此来判定这个请…...

项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统)
若该文为原创文章,转载请注明出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/142454993 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、Op…...

CSS开发全攻略
目录 一、CSS基础入门(一)CSS概述1.CSS的定义与作用2.CSS的历史与发展3.CSS的核心概念(1)选择器(Selector)(2)声明(Declaration)(3)规…...

OpenCV运动分析和目标跟踪(3)计算图像序列的加权平均值函数accumulateWeighted()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 更新一个运行平均值。 该函数计算输入图像 src 和累积器 dst 的加权和,使得 dst 成为帧序列的运行平均值: dst ( x , y…...

vue3中echarts柱状图横轴文字太多放不下怎么解决
问题:在做数据展示的时候,使用的是echarts,遇到了个问题,就是数据过多,但是设置的x轴的文字名称又太长,往往左边第一个或右边最后一个的名称展示不全,只有半个。 从网上找到了几种办法ÿ…...

Web 开发安全与最佳实践:MVC、会话管理与常见攻击防御
1. 引言 随着 Web 应用的普及,安全问题变得尤为重要。从小型个人网站到复杂的企业级系统,安全漏洞可能导致数据泄露、服务中断甚至经济损失。因此,在 Web 开发中,采用良好的架构设计、会话管理和安全防护机制至关重要。本文将探讨…...

Segformer双显卡推理速度测试
1、4080单显卡和双显卡同步并行推理平均耗时分别为360ms、600ms;双显卡速度明显比单显卡的速度快 2、两个相机间隔500ms的并行推理耗时,单双显卡推理平均耗时为340ms 3、4080双显卡和4070双显卡同步并行推理平均耗时分别为360ms、380ms;4080比4070的速度快20ms...

使用在线电子模拟器 Wokwi 运行 ESP32 示例(Arduino IDE、ESP32C3)
文章目录 Wokwi安装客户端(Mac/Linux)创建 Token ESP32C3 示例demo.ino创建模拟器运行模拟器 Wokwi Wokwi 是一款在线电子模拟器。您可以使用它来模拟 Arduino、ESP32、STM32 以及许多其他流行的主板、部件和传感器。 Github: https://gith…...