#!/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 位、颜色类型 2(RGB)的 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()