docs: add user manual (使用说明.docx) + generator script
scripts/gen_user_manual.py builds docs/使用说明.docx with python-docx (re-run to regenerate). Covers install/launch, UI overview, workflow, materials, preview fine-tuning, templates, batch modes/queue, export structure, settings + online update, data locations, and FAQ. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
"""Generate the user manual (docs/使用说明.docx) with python-docx.
|
||||
|
||||
Re-run to regenerate after editing the content below:
|
||||
python scripts/gen_user_manual.py
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from docx import Document
|
||||
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||||
from docx.shared import Pt, RGBColor
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
VERSION_FILE = os.path.join(ROOT, "src", "version.py")
|
||||
OUT = os.path.join(ROOT, "docs", "使用说明.docx")
|
||||
|
||||
|
||||
def read_version():
|
||||
name, ver = "自动化工具", "1.0.0"
|
||||
with open(VERSION_FILE, encoding="utf-8") as f:
|
||||
text = f.read()
|
||||
m = re.search(r'APP_NAME\s*=\s*"([^"]+)"', text)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
m = re.search(r'APP_VERSION\s*=\s*"([^"]+)"', text)
|
||||
if m:
|
||||
ver = m.group(1)
|
||||
return name, ver
|
||||
|
||||
|
||||
def main():
|
||||
app_name, app_version = read_version()
|
||||
doc = Document()
|
||||
|
||||
# Use a CJK-friendly default font.
|
||||
normal = doc.styles["Normal"]
|
||||
normal.font.name = "微软雅黑"
|
||||
normal.font.size = Pt(10.5)
|
||||
|
||||
title = doc.add_heading(app_name + " 使用说明", level=0)
|
||||
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
sub = doc.add_paragraph("版本 v%s" % app_version)
|
||||
sub.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
doc.add_paragraph()
|
||||
|
||||
def h(text, level=1):
|
||||
doc.add_heading(text, level=level)
|
||||
|
||||
def p(text):
|
||||
doc.add_paragraph(text)
|
||||
|
||||
def b(text):
|
||||
doc.add_paragraph(text, style="List Bullet")
|
||||
|
||||
def n(text):
|
||||
doc.add_paragraph(text, style="List Number")
|
||||
|
||||
# 1
|
||||
h("一、软件简介")
|
||||
p("%s 是一款 Windows 桌面工具,用于把印花图案批量合成到衣服底图上,并导出效果图。"
|
||||
"支持从文件夹(含子文件夹)批量导入素材、用模板统一摆放印花、对单张精细微调,"
|
||||
"并按多种批量模式一次性生成大量合成图。" % app_name)
|
||||
|
||||
# 2
|
||||
h("二、安装与启动")
|
||||
b("软件为「便携版」:把发布包解压到任意可写目录即可使用,例如 D:\\CMBot 或桌面。")
|
||||
b("双击目录里的 Launcher.exe 启动(不要直接运行 app 文件夹里的 CMBot.exe)。")
|
||||
b("请勿放在 C:\\Program Files 或 C:\\ 盘根目录——这些位置普通用户不可写,会导致更新失败。")
|
||||
b("首次启动会自动在你的用户目录创建配置;无需安装、不写注册表。")
|
||||
p("目录结构(解压后):")
|
||||
b("Launcher.exe —— 启动入口,负责应用更新并启动主程序。")
|
||||
b("app\\ —— 主程序本体(更新时会被整体替换)。")
|
||||
b("合并后的图片\\ —— 默认导出目录,就在程序旁,便于查找(可在软件里改)。")
|
||||
b("%USERPROFILE%\\.cmbot —— 你的配置、模板、日志(与程序位置无关,更新不丢)。")
|
||||
|
||||
# 3
|
||||
h("三、界面总览")
|
||||
p("主窗口从上到下分为四个区域:")
|
||||
b("顶部流程页签:1 添加印花(当前可用)、2 AI 穿搭、3 导出上架(暂未开放);最右侧是 ⚙ 配置 按钮。")
|
||||
b("左侧素材栏:上为「衣服图片」,下为「印花图片」,各自可打开文件夹、缩略图网格展示。")
|
||||
b("中间预览区:合成效果实时预览,可直接拖动 / 缩放 / 旋转印花。")
|
||||
b("右侧参数栏:模板、位置、尺寸、旋转、输出设置。")
|
||||
b("底部合成队列:批量任务列表与导出进度。")
|
||||
|
||||
# 4
|
||||
h("四、基本操作流程")
|
||||
n("点击「打开衣服文件夹」,选择存放衣服底图的文件夹(含子文件夹会一并导入)。")
|
||||
n("点击「打开印花文件夹」,选择印花图案文件夹。加载后会自动预览第一张组合。")
|
||||
n("在右侧「模板」下拉框选择一个模板,印花会按模板自动摆放到衣服上。")
|
||||
n("如需微调,在中间预览区直接拖动印花、拖四角缩放、拖顶部控制点旋转。")
|
||||
n("在底部选择批量模式,确认队列内容。")
|
||||
n("在「输出设置」选择格式与目录,点击底部「开始批量导出」。")
|
||||
|
||||
# 5
|
||||
h("五、素材选择")
|
||||
b("缩略图网格每行多张,随面板宽度自动换行。")
|
||||
b("勾选框(缩略图左上角)表示该素材是否参与批量合成;可「全选 / 取消全选」。")
|
||||
b("单击某张图片=把它设为当前预览(与是否勾选参与批量相互独立)。")
|
||||
b("支持格式:PNG、JPG、JPEG、WEBP;不支持的文件会被自动忽略。")
|
||||
b("软件会记住上次打开的衣服 / 印花文件夹位置。")
|
||||
|
||||
# 6
|
||||
h("六、预览与微调")
|
||||
p("预览顶部可切换操作模式(移动 / 缩放 / 旋转)并调整预览显示比例(不影响真实合成)。")
|
||||
b("移动:直接拖动印花。")
|
||||
b("缩放:拖动选中框四角;按住 Shift 锁定宽高比例。")
|
||||
b("旋转:拖动顶部的旋转控制点。")
|
||||
p("右侧参数栏可精确输入数值:")
|
||||
b("位置(X / Y)、尺寸(宽 / 高,可勾选「锁定宽高比例」)、旋转(角度,另有左旋 / 右旋 90°)。")
|
||||
b("每个分区标题右侧的「↺ 重置」只把该分区参数还原为当前模板值,三者互不影响。")
|
||||
b("参数栏底部「位置尺寸旋转重置为当前模板」一次性整体还原。")
|
||||
|
||||
# 7
|
||||
h("七、模板")
|
||||
b("模板用比例坐标保存印花的位置、大小、旋转,能适配任意尺寸的衣服图。")
|
||||
b("内置模板:正方形、纵向长方形、横向长方形、左胸小号等。")
|
||||
b("「保存」覆盖当前自定义模板,「另存为」新建模板,「删除」移除自定义模板(删除前会二次确认)。")
|
||||
b("内置模板不显示「保存 / 删除」。软件会记住上次选择的模板,下次启动自动恢复。")
|
||||
|
||||
# 8
|
||||
h("八、批量模式与队列")
|
||||
p("底部队列头部可切换批量模式:")
|
||||
b("全组合(矩阵):每件衣服 × 每个印花。")
|
||||
b("多衣服 × 单印花:所有衣服都用第一个印花。")
|
||||
b("单衣服 × 多印花:第一件衣服配所有印花。")
|
||||
b("一一匹配:按顺序一一对应。")
|
||||
p("队列表格显示每项的衣服、印花、来源文件夹、参数(模板 / 已微调)、状态与进度。")
|
||||
b("在队列中选中某项可加载到预览继续微调;微调后该项标记为「已微调」,批量导出时用它自己的参数,不被模板覆盖。")
|
||||
b("「开始批量导出」开始导出(可中途停止);「导出选中」只导出选中的一项;「重置全部」清空导出状态。")
|
||||
|
||||
# 9
|
||||
h("九、导出设置与输出结构")
|
||||
b("格式:PNG(保留透明)或 JPG;选 JPG 时可设质量。")
|
||||
b("输出目录默认是程序旁的「合并后的图片」文件夹,便于查找;可点「浏览」改成任意目录。")
|
||||
p("每次导出运行会按「时间戳 → 印花」两级分组,避免互相覆盖:")
|
||||
p(" 输出目录\\<时间戳>\\<印花名>\\<衣服名>_<印花名>.png")
|
||||
p("例如印花 TY030、衣服 1 → 合并后的图片\\20260618_153000\\TY030\\1_TY030.png。")
|
||||
|
||||
# 10
|
||||
h("十、设置与在线更新")
|
||||
p("点击右上角 ⚙ 配置 打开设置对话框:")
|
||||
b("更新地址 / 账号 / 密码:在线更新源(HTTP 文件服务)的地址与登录凭据。")
|
||||
b("测试连接:检查地址与账号是否可用,并显示远端版本。")
|
||||
b("检查并更新:下载新版本到本地暂存;下载在后台进行,不影响当前使用。")
|
||||
p("更新机制:")
|
||||
b("启动时自动后台检查;发现新版会在 ⚙ 配置 按钮左侧出现蓝色「发现新版本 vX.Y.Z」提示。")
|
||||
b("在设置里点「检查并更新」下载完成后,会提示「下次启动生效」。")
|
||||
b("下次双击 Launcher.exe 时自动切换到新版本(旧版本保留为 app.old 以便回滚)。")
|
||||
|
||||
# 11
|
||||
h("十一、数据与文件位置")
|
||||
b("配置、自定义模板、运行日志:%USERPROFILE%\\.cmbot(更新、重装都不会丢失)。")
|
||||
b("导出结果:默认在程序目录旁的「合并后的图片」文件夹。")
|
||||
b("程序本体:安装目录下的 app 文件夹(更新时整体替换,请勿在此存放个人文件)。")
|
||||
|
||||
# 12
|
||||
h("十二、常见问题")
|
||||
b("启动后没反应 / 提示无法启动:确认是双击 Launcher.exe,且程序未放在 C 盘根或 Program Files。")
|
||||
b("更新后还是旧版本:更新需要「下次启动生效」,请关闭程序后再用 Launcher.exe 启动一次。")
|
||||
b("提示安装目录不可写:把整个程序文件夹移到可写位置(如 D:\\CMBot)再运行。")
|
||||
b("找不到导出的图片:默认在程序旁的「合并后的图片」文件夹,或查看导出设置里显示的目录。")
|
||||
b("批量导出格式不对:在「输出设置」确认已选择目标格式(PNG / JPG)。")
|
||||
|
||||
doc.add_paragraph()
|
||||
tail = doc.add_paragraph("— 本说明随软件版本更新,如与实际界面不一致,以软件为准。—")
|
||||
tail.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
for run in tail.runs:
|
||||
run.font.size = Pt(9)
|
||||
run.font.color.rgb = RGBColor(0x88, 0x88, 0x88)
|
||||
|
||||
doc.save(OUT)
|
||||
print("written:", OUT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user