Files
scuc-qt-course/docs/teaching/examples/mainwindow_showcase/gen_icons.py
T
张宗平 05a685c952 Day3 教学示例:增强版计算器接入 + QMainWindow/QSS 两版参考实现
- calculator_designer_ext(Day2 增强版:表达式求值 + 括号,递归下降解析器)接入 cmake
- calculator_mainwindow(Day3 上午):增强版计算器装进 QMainWindow,
  菜单/状态栏/历史停靠窗,纯代码 + 显式 connect,与 mainwindow_showcase 形成坑卡对照
- calculator_mainwindow_qss(Day3 下午):上午版 + QSS 双主题美化(按键分色/伪状态/深浅切换)
- 验证 mainwindow_showcase(QMainWindow 六大组件综合演示,.ui + .qrc)
- OUTLINE_4DAY.md / ASSIGNMENTS.md Day3 衔接增强版起点 + 参考实现指引
- 补提交 Day2 calculator/ 与 calculator_designer/ 参考实现(CMakeLists 已引用)
- 全量构建 28/28,4 目标离屏自测退出码 0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 22:59:05 +08:00

84 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""生成 qt_mainwindow_showcase 所需的极简 PNG 图标。
仅用 Python 标准库(zlib + struct)手写最小 PNG 编码器,无第三方依赖。
幂等:重复运行覆盖生成相同文件。
python gen_icons.py # *nix / 已配置 py 启动器的 Windows
py gen_icons.py # Windows 官方 py 启动器
"""
import os
import struct
import zlib
HERE = os.path.dirname(os.path.abspath(__file__))
ICONS_DIR = os.path.join(HERE, "icons")
# 5×7 点阵字模("1" = 前景白色像素)
GLYPHS = {
"M": ["10001", "11011", "10101", "10001", "10001", "10001", "10001"],
"N": ["10001", "11001", "10101", "10011", "10001", "10001", "10001"],
"Q": ["01110", "10001", "10001", "10001", "10101", "10011", "01111"],
"A": ["01110", "10001", "10001", "11111", "10001", "10001", "10001"],
"D": ["11110", "10001", "10001", "10001", "10001", "10001", "11110"],
}
def write_png(path, width, height, rgb_rows):
"""写一张 8 位、颜色类型 2RGB)的 PNG。rgb_rows: 每行 width*3 个 0-255 整数。"""
def chunk(tag, data):
body = tag + data
return (struct.pack(">I", len(data)) + body +
struct.pack(">I", zlib.crc32(body) & 0xffffffff))
sig = b"\x89PNG\r\n\x1a\n"
ihdr = struct.pack(">IIBBBBB", width, height, 8, 2, 0, 0, 0)
raw = b"".join(b"\x00" + bytes(row) for row in rgb_rows) # 每行前加 filter byte(0)
idat = zlib.compress(raw, 9)
with open(path, "wb") as f:
f.write(sig + chunk(b"IHDR", ihdr) + chunk(b"IDAT", idat) + chunk(b"IEND", b""))
def make_icon(size, bg, letter):
"""生成 size×size 的像素矩阵:纯色背景 + 居中白色字母。"""
glyph = GLYPHS[letter]
bw, bh = 5, 7
pix = 1 if size <= 16 else 2 # 16px 用 1:1 字模,32px 放大 2 倍
gw, gh = bw * pix, bh * pix
ox = (size - gw) // 2
oy = (size - gh) // 2
rows = []
for y in range(size):
row = []
for x in range(size):
gx, gy = (x - ox) // pix, (y - oy) // pix
if 0 <= gx < bw and 0 <= gy < bh and glyph[gy][gx] == "1":
row.extend((255, 255, 255))
else:
row.extend(bg)
rows.append(row)
return rows
# (文件名, 尺寸, 背景色 RGB, 字母)
SPECS = [
("app.png", 32, (30, 80, 180), "M"),
("new.png", 16, (40, 150, 70), "N"),
("quit.png", 16, (200, 50, 50), "Q"),
("about.png", 16, (220, 140, 30), "A"),
("dock.png", 16, (130, 60, 180), "D"),
]
def main():
os.makedirs(ICONS_DIR, exist_ok=True)
for name, size, bg, letter in SPECS:
write_png(os.path.join(ICONS_DIR, name), size, size, make_icon(size, bg, letter))
print(f"wrote {name} ({size}x{size})")
print(f"done -> {ICONS_DIR}")
if __name__ == "__main__":
main()