当前位置: 首页 > news >正文

python打包辅助工具

python打包辅助工具

PyInstaller 是一个非常流行的 Python 应用程序打包工具,它可以将 Python 脚本及其依赖项打包成独立的可执行文件,方便在没有 Python 环境的机器上运行。关于PyInstaller,可参见:https://blog.csdn.net/cnds123/article/details/115254418

PyInstaller打包过程对新手来说,实在是太麻烦了,能否用Tkinter实现GUI界面包装PyInstaller,方便使用呢?我这里给出一个实现。

界面上:

主脚本文件(必选)框及“浏览”按钮

exe图标(可选)框及“浏览”按钮

资源文件(--add-data)框及“浏览”按钮 (这个是多行框每按一次按钮添加一行,旁边应有删除行按钮,用于删除误加入的行)

隐藏控制台复选框

单文件(--onefile)和单文件夹 (--onedir,默认)处理 单选框

打包输出保存框(可选)及“浏览”按钮,不选默认在主脚本文件所在文件夹

打包信息框(这个应是多行框),用于显示进度或错误信息等

“路径合规检测”按钮,“sys._MEIPASS检测”用于要检查相关资源文件是否符合要求,检测 源码是否sys._MEIPASS动态拼接资源路径,如不符合,自动添加 resource_path(relative_path)函数,并此处理源码在相关资源文件路径合规。

“打包”按钮,执行打包生成exe文件

运行显示效果

本程序使用了一些模块是 Python 标准库的一部分,通常不需要额外安装,因为它们随 Python 解释器一起提供。

(1)tkinter:

Python 的标准 GUI 库,用于创建图形用户界面。

(2)subprocess:

用于运行外部命令和程序。

(3)sys:

提供对 Python 解释器的访问,例如获取命令行参数、退出程序等。

(4)os:

提供操作系统相关的功能,如文件路径操作、环境变量等。

(5)re:

提供正则表达式支持,用于字符串匹配和处理。

(6)threading:

提供线程支持,用于并发编程。

(7)

提供文件和文件集合的高级操作,如复制、移动、删除等。

源码如下:

import tkinter as tk
from tkinter import ttk, filedialog, scrolledtext, messagebox
import subprocess
import sys
import os
import re
import threading
import shutilclass PyInstallerGUI:def __init__(self, root):self.root = rootself.root.title("PyInstaller GUI 打包工具 v1.2")self.setup_ui()self.resource_entries = []self.current_output = ""# 设置日志重定向self.redirect_output()def setup_ui(self):main_frame = ttk.Frame(self.root, padding=10)main_frame.pack(fill=tk.BOTH, expand=True)# 主脚本文件ttk.Label(main_frame, text="主脚本文件:").grid(row=0, column=0, sticky=tk.W)self.script_entry = ttk.Entry(main_frame, width=50)self.script_entry.grid(row=0, column=1, padx=5)ttk.Button(main_frame, text="浏览", command=self.browse_script).grid(row=0, column=2)# 图标文件ttk.Label(main_frame, text="EXE图标:").grid(row=1, column=0, sticky=tk.W)self.icon_entry = ttk.Entry(main_frame, width=50)self.icon_entry.grid(row=1, column=1, padx=5)ttk.Button(main_frame, text="浏览", command=self.browse_icon).grid(row=1, column=2)# 资源文件resource_frame = ttk.LabelFrame(main_frame, text="资源文件 (--add-data)")resource_frame.grid(row=2, column=0, columnspan=3, sticky=tk.W+tk.E, pady=5)self.resource_list = ttk.Frame(resource_frame)self.resource_list.pack(fill=tk.X)btn_frame = ttk.Frame(resource_frame)btn_frame.pack(fill=tk.X)ttk.Button(btn_frame, text="添加资源", command=self.add_resource_row).pack(side=tk.LEFT)ttk.Button(btn_frame, text="清空所有", command=self.clear_resources).pack(side=tk.LEFT)# 打包选项option_frame = ttk.Frame(main_frame)option_frame.grid(row=3, column=0, columnspan=3, sticky=tk.W, pady=5)self.console_var = tk.IntVar(value=1)ttk.Checkbutton(option_frame, text="隐藏控制台", variable=self.console_var).pack(side=tk.LEFT, padx=10)self.mode_var = tk.StringVar(value="--onedir")ttk.Radiobutton(option_frame, text="单文件夹", variable=self.mode_var, value="--onedir").pack(side=tk.LEFT)ttk.Radiobutton(option_frame, text="单文件", variable=self.mode_var,value="--onefile").pack(side=tk.LEFT)# 输出目录ttk.Label(main_frame, text="输出目录:").grid(row=4, column=0, sticky=tk.W)self.output_entry = ttk.Entry(main_frame, width=50)self.output_entry.grid(row=4, column=1, padx=5)ttk.Button(main_frame, text="浏览", command=self.browse_output).grid(row=4, column=2)# 代码检测ttk.Button(main_frame, text="路径合规检测", command=self.check_code).grid(row=5, column=0, pady=5)# 打包按钮ttk.Button(main_frame, text="开始打包", command=self.start_build).grid(row=5, column=1, pady=5)# 日志输出self.log_area = scrolledtext.ScrolledText(main_frame, width=80, height=15)self.log_area.grid(row=6, column=0, columnspan=3, pady=10)def add_resource_row(self, path=""):row_frame = ttk.Frame(self.resource_list)row_frame.pack(fill=tk.X, pady=2)entry = ttk.Entry(row_frame, width=60)entry.pack(side=tk.LEFT, padx=5)entry.insert(0, path)ttk.Button(row_frame, text="浏览", command=lambda e=entry: self.browse_resource(e)).pack(side=tk.LEFT)ttk.Button(row_frame, text="×", command=lambda f=row_frame: self.remove_resource_row(f)).pack(side=tk.LEFT)self.resource_entries.append(entry)def remove_resource_row(self, frame):for entry in self.resource_entries:if entry.master == frame:self.resource_entries.remove(entry)breakframe.destroy()def clear_resources(self):for entry in self.resource_entries.copy():self.remove_resource_row(entry.master)def browse_script(self):path = filedialog.askopenfilename(filetypes=[("Python文件", "*.py")])if path:self.script_entry.delete(0, tk.END)self.script_entry.insert(0, path)self.output_entry.delete(0, tk.END)self.output_entry.insert(0, os.path.dirname(path))def browse_icon(self):path = filedialog.askopenfilename(filetypes=[("图标文件", "*.ico")])if path:self.icon_entry.delete(0, tk.END)self.icon_entry.insert(0, path)def browse_output(self):path = filedialog.askdirectory()if path:self.output_entry.delete(0, tk.END)self.output_entry.insert(0, path)def browse_resource(self, entry):if os.path.isdir(entry.get()):path = filedialog.askdirectory(initialdir=entry.get())else:path = filedialog.askopenfilename(initialdir=os.path.dirname(entry.get()))if path:entry.delete(0, tk.END)entry.insert(0, path)def check_code(self):script_path = self.script_entry.get()if not script_path:messagebox.showerror("错误", "请先选择主脚本文件")returntry:with open(script_path, 'r', encoding='utf-8') as f:content = f.read()# 创建备份backup_path = script_path + '.bak'shutil.copy2(script_path, backup_path)# 更新模式以捕获更多类型的函数调用,包括pygame.image.load()patterns = [r"((?:[\w.]+\.)*(?:open|load|Image\.open))\((['\"])(?!(?:https?:|[\\/]|resource_path\())[^'\"]+\2\)"]issues = []modified_content = contentself.log_area.delete('1.0', tk.END)for pattern in patterns:matches = list(re.finditer(pattern, content))for match in reversed(matches):  # 从后向前替换,以避免影响索引if not self.is_in_comment(content, match.start()):full_match = match.group(0)func_name = match.group(1)quote = match.group(2)path = full_match[len(func_name)+2:-2]  # 提取路径,去掉引号line_number = content[:match.start()].count('\n') + 1issues.append(f"第{line_number}行: 发现硬编码路径 - {full_match}")replacement = f"{func_name}(resource_path({quote}{path}{quote}))"modified_content = modified_content[:match.start()] + replacement + modified_content[match.end():]# 详细输出替换信息self.log_area.insert(tk.END, f"替换第{line_number}行:\n原始: {full_match}\n替换为: {replacement}\n\n")sys_import = re.search(r"import\s+sys", content)os_import = re.search(r"import\s+os", content)resource_path_func = re.search(r"def\s+resource_path", content)if not resource_path_func:issues.append("未找到resource_path函数")if issues:msg = "检测到以下路径问题:\n\n" + "\n".join(issues)self.log_area.insert(tk.END, "完整的修改后代码:\n\n" + modified_content)if messagebox.askyesno("检测结果", msg + "\n\n修改详情已显示在日志框中。是否应用这些修改?"):self.fix_code_issues(script_path, modified_content, sys_import, os_import, resource_path_func)else:messagebox.showinfo("检测结果", "代码路径处理符合规范")except Exception as e:messagebox.showerror("错误", f"文件读取失败:{str(e)}")            def is_in_comment(self, content, position):line_start = content.rfind('\n', 0, position) + 1line = content[line_start:content.find('\n', position)]return '#' in line[:position - line_start]def fix_code_issues(self, path, content, sys_import, os_import, resource_path_func):imports = ""if not sys_import:imports += "import sys\n"if not os_import:imports += "import os\n"# 改进的resource_path函数,不包含任何缩进resource_path_code = '''def resource_path(relative_path):""" 获取资源的绝对路径,支持开发环境和PyInstaller打包后的环境 """try:# PyInstaller创建临时文件夹,将路径存储在_MEIPASS中base_path = sys._MEIPASSexcept Exception:# 如果不是打包环境,则使用当前文件的目录base_path = os.path.abspath(".")return os.path.join(base_path, relative_path)'''if not resource_path_func:# 在import语句之后添加resource_path函数import_end = content.rfind('import')if import_end == -1:# 如果没有import语句,则在文件开头添加content = imports + "\n" + resource_path_code.strip() + "\n\n" + contentelse:import_end = content.find('\n', import_end) + 1# 确保resource_path函数与其他代码保持一致的缩进indent = self.get_indent(content)indented_resource_path_code = self.indent_code(resource_path_code.strip(), indent)content = content[:import_end] + imports + "\n" + indented_resource_path_code + "\n\n" + content[import_end:]try:with open(path, 'w', encoding='utf-8') as f:f.write(content)messagebox.showinfo("成功", "代码已成功修复")except Exception as e:messagebox.showerror("错误", f"文件写入失败:{str(e)}")# 在日志区域显示修改后的代码self.log_area.delete('1.0', tk.END)self.log_area.insert(tk.END, "修改后的代码:\n\n" + content)def get_indent(self, content):"""获取代码的主要缩进"""lines = content.split('\n')for line in lines:if line.strip() and not line.strip().startswith('#'):return line[:len(line) - len(line.lstrip())]return ''def indent_code(self, code, indent):"""给代码块添加缩进"""lines = code.split('\n')indented_lines = [indent + line if line.strip() else line for line in lines]return '\n'.join(indented_lines)def start_build(self):os.environ['PYTHONIOENCODING'] = 'utf-8' #处理在日志区显示的中文(如路径中的中文)乱码if not self.script_entry.get():messagebox.showerror("错误", "必须选择主脚本文件")returncmd = ["pyinstaller"]if self.mode_var.get() == "--onefile":cmd.append("--onefile")else:cmd.append("--onedir")if self.console_var.get() == 1:cmd.append("--noconsole")if self.icon_entry.get():cmd.extend(["--icon", f'"{self.icon_entry.get()}"'])for entry in self.resource_entries:if entry.get():src, dest = self.parse_resource(entry.get())if src and dest:cmd.append(f'--add-data="{src};{dest}"')output_dir = self.output_entry.get()if output_dir:cmd.extend(["--distpath", f'"{output_dir}"'])cmd.append(f'"{self.script_entry.get()}"')self.log_area.delete('1.0', tk.END)self.log_area.insert(tk.END, "生成命令:\n" + " ".join(cmd) + "\n\n")threading.Thread(target=self.run_command, args=(cmd,), daemon=True).start()def parse_resource(self, path):if os.path.isfile(path):# 对于文件,保留其相对路径结构script_dir = os.path.dirname(self.script_entry.get())if path.startswith(script_dir):rel_path = os.path.relpath(path, script_dir)dest_dir = os.path.dirname(rel_path)if not dest_dir:dest_dir = "."return path, dest_direlse:return path, "."elif os.path.isdir(path):# 对于目录,保留目录名return os.path.join(path, "*"), os.path.basename(path)return None, Nonedef run_command(self, cmd):try:process = subprocess.Popen(" ".join(cmd),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True,encoding='utf-8',errors='replace')while True:output = process.stdout.readline()if output == '' and process.poll() is not None:breakif output:self.log_area.insert(tk.END, output)self.log_area.see(tk.END)self.log_area.update()if process.returncode == 0:messagebox.showinfo("完成", "打包成功完成!")else:messagebox.showerror("错误", f"打包失败,错误码:{process.returncode}")except Exception as e:messagebox.showerror("异常", f"执行出错:{str(e)}")def redirect_output(self):class StdoutRedirector:def __init__(self, text_widget):self.text_widget = text_widgetdef write(self, message):self.text_widget.insert(tk.END, message)self.text_widget.see(tk.END)sys.stdout = StdoutRedirector(self.log_area)sys.stderr = StdoutRedirector(self.log_area)if __name__ == "__main__":root = tk.Tk()app = PyInstallerGUI(root)root.mainloop()

最后,特别提示,本程序是PyInstaller外壳,因此,必须先安装PyInstaller。

 

相关文章:

python打包辅助工具

python打包辅助工具 PyInstaller 是一个非常流行的 Python 应用程序打包工具,它可以将 Python 脚本及其依赖项打包成独立的可执行文件,方便在没有 Python 环境的机器上运行。关于PyInstaller,可参见:https://blog.csdn.net/cnds1…...

jangow靶机攻略

配置网卡 VMware需要配置,不配置扫不到ip,VirtualBox正常打开ip会直接显示出来 网卡配置都改成NAT 打开虚拟机,第一个框选第二行,回车 选第二个,按e键 进入下一个框后,将ro 后面的修改为 rw signin init/bin/bash 按…...

【大模型LLM第十四篇】Agent学习之anthropic-quickstarts Agent

前言 对于anthropic api的快速使用,在github上有几个example Customer Support Agent:由 Claude 提供支持的客户支持代理。该项目演示了如何利用 Claude 的自然语言理解和生成功能来创建可访问知识库的 AI 辅助客户支持系统。Financial Data Analyst &…...

MonIo部署

1、命令行安装 访问monio官网下载应用程序 # wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20250228095516.0.0-1.x86_64.rpm -O minio.rpm # sudo dnf install minio.rpm # mkdir ~/minio # minio server ~/minio --console-address :90012、dock…...

深入理解智能家居领域中RS485、Modbus、KNX 和 Zigbee协议概念

首先详细介绍一下 RS485 和 Modbus 这两个在工业自动化和数据通讯领域中非常重要的概念。 RS485 1. 定义与特点 RS485 标准:RS485 是一种串行通信标准,也称为TIA-485标准,主要用于数据传输。它规定了物理层的电气特性,与数据格式…...

Spring Boot深度解析:从核心原理到最佳实践

一、Spring Boot概述 Spring Boot作为Spring生态中的"游戏规则改变者",自2014年发布以来彻底改变了Java企业级应用的开发方式。它通过四大核心特性显著提升了开发效率: 自动配置:基于类路径和已有Bean的智能默认配置起步依赖:简化Maven/Gradle依赖管理的Starter…...

MapReduce过程中reduce task的数量是如何确定的?

在Hadoop MapReduce及Hive中,numReduceTasks(Reduce任务数量)的确定由用户显式设置、框架自动估算、作业特性约束三方面共同决定。以下是详细解析及示例: 1. 用户显式设置 用户可以通过代码或配置参数直接指定Reduce任务数&#…...

【euclid】21 3D包围盒模块(box3d.rs)

box3d.rs文件定义了一个三维轴对齐的矩形框(Box3D),使用最小和最大坐标来表示。矩形框在坐标类型(T)和单位(U)上是泛型的。代码提供了多种方法来操作和查询矩形框,包括求交集、并集、…...

用selenium+ChromeDriver豆瓣电影 肖申克的救赎 短评爬取(pycharm 爬虫)

一、豆瓣电影 肖申克的救赎 短评url=https://movie.douban.com/subject/1292052/comments 二、基本知识点讲解 1. Selenium 的基本使用 Selenium 是一个用于自动化浏览器操作的库,常用于网页测试和爬虫。代码中使用了以下 Selenium 的核心功能: webdriver.Chrome: 启动 Chr…...

mysql入门操作

目录 一,MySQL简述 1,什么是MySQL 2,什么是SQL 3,SQL的分类 二,数据库的数据存储类型 1,数值类型 2,字符串类型 3,时间和日期类型 三,数据库的基本操作 1&…...

机械臂【逆运动学】

回顾正运动学fk: IK: 几何法 代数法 六轴 456轴交再同一点 有解析解 下列公式为正运动学部分结论 a和d是长度 ,theta和alfa是角度 **疑问:alfa00? Z轴互相平行 ** 已知末端要在空间XYZ处如下 绿色项&#x…...

思库拉水厂开业庆典千人大会回顾

近日,思库拉离子水厂在广州隆重举办了开业盛典,现场汇聚了逾千名嘉宾。此次盛会不仅是对思库拉离子水厂正式投产的庆祝,更是对思库拉品牌未来蓝图的一次展示。 现场氛围热烈,洋溢着浓厚的喜庆气息。参与者来自五湖四海,既有思库拉的忠实拥趸,也有对思库拉产品充满兴趣的潜在消费…...

将Wi-Fi模块订阅MQTT主题以获取最新的固件版本推送信息

将Wi-Fi模块订阅MQTT主题以获取最新的固件版本推送信息,是一种常见的物联网(IoT)应用场景。这种设计可以实现远程监控和设备的OTA(Over-The-Air)升级功能。以下是详细的实现步骤和技术细节: 一、系统架构概…...

Netty源码—5.Pipeline和Handler一

大纲 1.Pipeline和Handler的作用和构成 2.ChannelHandler的分类 3.几个特殊的ChannelHandler 4.ChannelHandler的生命周期 5.ChannelPipeline的事件处理 6.关于ChannelPipeline的问题整理 7.ChannelPipeline主要包括三部分内容 8.ChannelPipeline的初始化 9.ChannelPi…...

Vue 中的nextTick函数的原理、作用及使用场景。

大白话Vue 中的nextTick函数的原理、作用及使用场景 在 Vue 里,nextTick 函数是个超实用的工具,它能让你在 DOM 更新完成之后再执行代码。为了能更好地理解 nextTick 函数的原理,咱们就来深入剖析一下。 核心思路 Vue 里的数据更新是异步执…...

详细讲解css的穿透方法

样式穿透(CSS穿透)的几种方法,包括在Vue中使用::v-deep、>>>、/deep/,还有pointer-events属性。还有关于Shadow DOM和::part伪元素的内容。接下来我会把这些方法分类,并详细说明每种方法的适用场景和注意事项…...

深入理解 tree 命令行工具:目录结构可视化的利器

文章目录 前言1. 什么是 tree 命令?安装 tree 2. tree 的基本用法显示当前目录的树状结构显示指定目录的树状结构 3. tree 的常用选项3.1 显示隐藏文件3.2 排除特定目录或文件3.3 限制递归深度3.4 显示文件大小3.5 显示文件的权限信息3.6 将输出保存到文件 4. 实际应…...

【QA】QT中事件和信号的区别以及联系是什么?

在 Qt 中,事件(Event) 和 信号与槽(Signals & Slots) 是 GUI 编程的核心机制,它们既有联系又有本质区别。以下从底层原理、触发流程、代码实现、适用场景四个维度展开对比,并通过大量示例说…...

C++实用函数:find与find_if

本篇来介绍C++中find和find_if函数的使用,通过多个实例来演示。 find用于基础的查找功能,find_if可以实现更复杂的匹配查找条件。 1 find 1.1 函数原型 template <class InputIterator, class T> InputIterator find ( InputIterator first, InputIterator last, c…...

全面了解 Cookies、Session 和 Token

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

酷淘商场项目【从零到一详解】Web端

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…...

如何转移虚拟主机?最新虚拟主机迁移方法

转移网站并不困难&#xff0c;但选择正确的选项和最佳程序才是关键。网站托管服务被视为当今数字世界的基石&#xff0c;全球有18 亿个网站。网站所有者可以通过下载备份、将其上传到新服务器并指向域名来手动转移网站。他们还可以通过新网站托管商的助手请求来移动网站。对于初…...

JVM 核心知识点总结

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

无人机数据链技术详解,无人机图传数传技术,无人机数据传输技术原理

以下是对无人机数据链技术、无人机图传数传技术以及无人机数据传输技术原理的详细解释&#xff1a; 无人机数据链技术 无人机数据链是任务机、地面控制站之间&#xff0c;以及任务机与中继机、武器系统或其它操作平台之间&#xff0c;按照约定的通信协议和信息传输方式&#…...

【Linux】同步原理剖析及模拟BlockQueue生产消费模型

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

【AVRCP】GOEP互操作性深度解析:蓝牙封面艺术传输的技术实现与演进

目录 一、技术基础&#xff1a;协议架构与核心概念 1.1 GOEP协议体系解析 1.2 IrOBEX协议关键技术 1.3 版本强制性要求 1.4 关键特性对比&#xff08;GOEP v2.0 vs v1.1&#xff09; 1.5 关键技术实现细节 1.6 GOEP v2.0互操作性要求 1.7 IrOBEX v1.5互操作性要求 二、…...

三分钟读懂微服务

一、什么是微服务 微服务&#xff0c;简单来说&#xff0c;就是把一个庞大复杂的软件系统&#xff0c;拆分成一个个小型的、独立的服务模块。打个比方&#xff0c;一个大型商场就如同传统的单体架构软件系统&#xff0c;里面所有的店铺、设施都紧密关联在一起。而微服务架构下…...

《Oracle DBA入门实战:十大高频问题详解与避坑指南》

Oracle DBA 入门作业十问十答 本文为 Oracle DBA 入门作业整理&#xff0c;涵盖工具使用、配置管理及权限控制等核心知识点&#xff0c;适合新手快速上手。 如有疑问或补充&#xff0c;欢迎评论区交流&#xff01; 1. DBA 常用工具有哪些&#xff1f; Oracle Universal Instal…...

深入剖析 Android Compose 框架的自动动画:AnimatedVisibility 与 AnimatedContent(二十四)

深入剖析 Android Compose 框架的自动动画&#xff1a;AnimatedVisibility 与 AnimatedContent 引言 在 Android 应用开发中&#xff0c;动画是提升用户体验的重要手段。它能够让界面元素的显示与隐藏、状态的切换变得更加自然和流畅&#xff0c;避免生硬的变化给用户带来不佳…...

【线程安全问题的原因和方法】【java形式】【图片详解】

在本章节中采用实例图片的方式&#xff0c;以一个学习者的姿态进行描述问题解决问题&#xff0c;更加清晰明了&#xff0c;以及过程中会发问的问题都会一一进行呈现 目录 线程安全演示线程不安全情况图片解释&#xff1a; 将上述代码进行修改【从并行转化成穿行的方式】不会出…...

Cocos Creator Shader入门实战(六):使用setProperty动态设置材质属性,以及材质常用接口

引擎&#xff1a;3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 上篇文章&#xff0c;我们主要讲解了关于材质的使用&#xff0c;主要有这么几点&#xff1a; 一、没有Effect资源&#xff0c;材质无从说起。 二、材质的构建&#xff0c;支持编译器和代码的动态构建 三…...

编程题记录3

九宫幻方 题目链接&#xff1a;https://www.lanqiao.cn/problems/100/learning/?page1&first_category_id1&second_category_id3&tags%E7%9C%81%E8%B5%9B&tag_relationintersection 先旋转、镜像得到所有的情况&#xff0c;可以发现情况是可以暴力得出的。…...

Geotools自动识别SLD并生成图例图片实战-以Polygon数据为例

目录 前言 一、Geotools与SLD制图基础 1、SLD是什么 2、SLD有什么用 二、SLD文件的解析与读取 1、SLD结构介绍 2、SLD实例展示 3、SLD读取方法 三、图例生成与展示 1、图例生成流程 2、图例生成实战 3、图例生成展示 四、结论 前言 在地理信息系统&#xff08;GIS&…...

windows docker如何修改 默认的Container memory usage

参考:https://forums.docker.com/t/docker-on-windows-11-with-wsl2-does-not-use-the-memory-i-set-in-wslconfig/144404/3 参考:https://learn.microsoft.com/en-us/windows/wsl/wsl-config...

LabVIEW液压传动系统教学仿真平台

本文介绍了一种基于LabVIEW的液压传动系统教学仿真平台&#xff0c;该平台采用“老师讲解、线上仿真、线下操作”的复合实验模式&#xff0c;旨在提高实验教学的效率与安全性。通过实例验证&#xff0c;展示了该平台在教学和实际操作中的应用效果&#xff0c;同时也为液压传动系…...

Java实习生面试题(2025.3.23 be)

一、v-if与v-show的区别 v-show 和 v-if 都是 Vue 中的条件渲染指令&#xff0c;它们的主要区别在于渲染策略&#xff1a;v-if 会根据条件决定是否编译元素&#xff0c;而 v-show 则始终编译元素&#xff0c;只是通过改变 CSS 的 display 属性来控制显示与隐藏。 二、mybatis-…...

OpenCV第2课 OpenCV的组成结构与图片/视频的加载及展示

1.OpenCV 的组成结构 2.OpenCV 的具体模块 3. 图像的读取 4. 视频的读取 1.OpenCV 的组成结构 OpenCV 是由很多模块组成的,这些模块可以分成很多层: 最底层是基于硬件加速层(HAL)的各种硬件优化。再上一层是opencv_contrib 模块所包含的OpenCV 由其他开发人员所贡献的代…...

Blender导出fbx到Unity找不到贴图的问题

fbx导入Unity材质能不能找到贴图是一件玄学的事情。常见的情况是有些材质能找到&#xff0c;有些找不到&#xff1a; 可能有用的方法 解决方法1&#xff1a;把贴图文件复制过去&#xff0c;模型reimport&#xff1b; 解决方法2&#xff1a;导出时路径模式选复制&#xff0c;内…...

kafka的文章

1.面试的问题 要点 至多一次、恰好一次数据一致性超时重试、幂等消息顺序消息挤压延时消息 1.1 kafaka 生产消息的过程。 在消息发送的过程中&#xff0c;涉及到了两个线程&#xff0c;一个是main 线程&#xff0c;一个是sender 线程。在main 线程中创建了一个双端队列 Reco…...

Go常见问题与回答(下)

文章目录 1、通过指针变量 p 访问其成员变量 name&#xff0c;有哪几种方式&#xff1f;2、代码&#xff0c;说出结果3、扩容提&#xff0c;代码&#xff0c;说出结果4、指出下面这段代码的错误之处5、是否通过编译6、关于字符串连接&#xff0c;下面语法正确的是7、关于iota&a…...

vue3中如何缓存路由组件

在 Vue3 中缓存路由组件&#xff0c;主要借助<keep-alive>组件来实现&#xff0c;具体方法如下&#xff1a; 1. 全局缓存路由组件 在 App.vue 等根组件中&#xff0c;直接将<router-view>包裹在<keep-alive>标签内&#xff0c;这样所有的路由组件都会被缓存…...

云服务器怎么防御ddos攻击呢?

防御DDoS攻击是保障云服务器稳定运行的关键措施&#xff0c;以下是综合多种防护策略的详细方案&#xff1a; 1. 启用云服务商提供的DDoS防护服务 高防IP/流量清洗&#xff1a; 将业务流量接入云服务商的高防IP&#xff0c;由专业清洗中心过滤恶意流量&#xff0c;仅放行正常请求…...

Log4j2 的核心实现和源码分析

Log4j2 的核心实现和源码分析 1. 核心组件 1.1 Logger 功能:负责记录日志信息。实现:org.apache.logging.log4j.Logger 接口,org.apache.logging.log4j.core.Logger 类。1.2 Appender 功能:负责将日志信息输出到不同的目的地,如文件、控制台等。实现:org.apache.loggin…...

【深度学习】【目标检测】【OnnxRuntime】【C++】YOLOV3模型部署

【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV3模型部署 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV3模型部署前言Windows平台搭建依赖环境模型转换--pytorch转onnxONNXRuntime推…...

四种跨模态行人重识别可视化方法

1.Gradcam 2.检索可视化 3.tsne图 4.距离分布 需要的私聊&#xff0c;代码需要付费...

8个DeepSeek文章润色指令

今天道叔给各位文字工作者安利DeepSeek的8个神仙级润色指令(附真实案例拆解)&#xff0c;建议搭配冰美式食用更佳↓↓↓ 一、【学术黑话翻译器】 适用场景&#xff1a;给投资人看的BP/行业白皮书/专家访谈实录 指令公式&#xff1a;"将以下内容转化为通俗易懂的行业洞察…...

解决PowerShell下Git中文乱码问题

解决PowerShell下Git中文乱码问题 在使用Git进行版本控制时&#xff0c;许多开发者可能会遇到中文乱码的问题&#xff0c;尤其是在Windows环境下使用PowerShell时。这不仅影响代码的阅读和提交&#xff0c;还可能导致一些不可预见的错误。本文将详细探讨如何在PowerShell下解决…...

oracle数据库(数据库启动关闭/sqlplus登录及基本操作/设置字符集/distinct去重)

目录 1. Oracle数据库启动 2. Oracle数据库关闭 3. sqlplus登录Oracle数据库 3.1 使用sqlplus登录Oracle数据库 3.2 使用sqlplus登录Oracle数据库 3.3 远程登录 3.4 解锁用户 3.5 修改用户密码 3.6 查看当前语言环境 4. sqlplus基本操作 4.1 显示当前用户 4.2 查看当前用户…...

mapreduce时,客户端做哪些事

在MapReduce过程中&#xff0c;客户端&#xff08;Client&#xff09;是用户提交作业的入口&#xff0c;负责作业的初始化、配置、资源提交和作业监控。以下是客户端在整个流程中的具体职责和操作步骤&#xff1a; 1. 作业配置与参数解析 设置作业属性&#xff1a; 定义MapRed…...

DeepBI:重构流量逻辑,助力亚马逊广告实现高效流量增长

在日益激烈的跨境电商竞争环境中&#xff0c;广告投放早已从“粗放撒网”走向“精细化运营”。尤其是在亚马逊这样一个成熟且竞争白热化的平台&#xff0c;如何在广告预算有限的前提下实现高效曝光、精准触达、稳定转化&#xff0c;成为众多卖家和运营团队面临的核心挑战。 De…...