Skip to content

Icons and metadata

An app’s identity is a few small things: its name, its icon, its version, who publishes it and, on macOS, its bundle identifier. All of them are set in [tool.pyzed.build] of pyproject.toml, by hand or from the Export dialog of Pyzed Design, and pyzed build writes them where each system looks.

pyproject.toml
[tool.pyzed.build]
name = "Shop" # Shop.exe, Shop.app, dist/Shop/
version = "1.2.0" # default: [project] version
publisher = "Acme"
identifier = "com.acme.shop" # default: com.<publisher>.<name>
description = "Point of sale" # default: [project] description
copyright = "© 2026 Acme"
What Windows macOS Linux
name Shop.exe, the product name Shop.app, CFBundleDisplayName The executable
version File and product version (Details tab) CFBundleShortVersionString and CFBundleVersion -
publisher Company name - -
identifier - CFBundleIdentifier The windows’ app id (see The window icon)
description File description - -
copyright Legal copyright NSHumanReadableCopyright -

With PyInstaller, pyzed build writes a Windows version file (build/pyzed/version.txt) and fills in the bundle’s Info.plist after the build; Nuitka gets the same values as options.

Use a reverse domain you own as the identifier. macOS keeps the app’s preferences and privacy permissions under it, so do not change it between releases.

The window title is not here: it is the form’s Title in the designer, or title of your pz.App.

If your app shows its version or checks for updates, keep the version in your code too, for example in your package’s __init__.py, and update it together with pyproject.toml:

src/shop/__init__.py
__version__ = "1.2.0"

Give icon one square picture, ideally a PNG of 1024 × 1024 pixels with a transparent background:

pyproject.toml
[tool.pyzed.build]
icon = "assets/icon.png"

pyzed build makes every file the systems want from it, with Pyzed’s own image code (no Pillow, sips or iconutil needed), in build/pyzed/:

File Sizes inside Used for
app-icon.ico 16, 20, 24, 32, 40, 48, 64, 128, 256 px The Windows .exe: Explorer, the taskbar, Alt+Tab
app-icon.icns 16 to 1024 px, with Retina sizes The macOS bundle: Finder and the Dock
app-icon.png 256 px The icon of the app’s windows (shipped inside the app)

Small sizes are made by scaling the big picture down. If the 16 and 32 pixel versions look blurry, draw a simpler version for them yourself (below), or keep the design bold. The Export dialog previews every size.

An .ico or .icns file given as icon is used as it is, for its own system.

For full control over each size, make the files with your favorite tool from a 1024 × 1024 PNG:

from PIL import Image # pip install pillow
Image.open("icon.png").save("icon.ico", sizes=[(s, s) for s in (16, 24, 32, 48, 64, 128, 256)])

The .exe and .app icons are the ones of the file. A packaged app also gives its windows the icon (the title bar and the taskbar on Windows and Linux): the launcher sets pz.Window.icon to app-icon.png. macOS always shows the bundle’s icon in the Dock.

In your own code, any window can have its icon, a path to an image or its bytes:

import pyzed as pz
class Shop(pz.App):
icon = "assets/icon.png"
app_id = "com.acme.shop" # Linux: matches the .desktop file

On Linux, app_id names the app to the desktop. Wayland takes the icon of the taskbar and the dock from the .desktop file whose name matches it (com.acme.shop.desktop, see Linux); X11 uses icon directly.

To write a version resource of your own instead of the generated one (more fields, other languages), capture one from an existing .exe with pyi-grab_version and pass it to PyInstaller:

pyproject.toml
[tool.pyzed.build.pyinstaller]
args = ["--version-file", "assets/version.txt"]

Paths in args reach PyInstaller unchanged, and PyInstaller writes its spec file to build/pyzed/: if it cannot find the file, give its absolute path.