A professional color picker and converter built with PySide6 (Qt 6 for Python).
- Open any
.png/.jpg/.jpeg/.bmp/.webpimage - Eyedropper cursor activates on hover
- Real-time pixel loupe — 9×9 zoomed pixel grid with crosshair
- Color preview strip beneath the loupe shows the live hex value
- Click to sample → all 8 color-space cards update instantly
- Eight editable color-space fields, always in sync
- Large color preview bar shows the current color
- Edit any field (RGB, HEX, HSL, HSV, LAB, LCH, OKLab, OKLCH) → all others update
- Copy-to-clipboard button on every card
- Status bar shows current color in HEX + RGB + HSL at all times
- Dark studio theme (indigo-violet accent, monospace code values)
colorpick/
├── main.py ← Entry point
├── requirements.txt
└── app/
├── models/
│ └── color_model.py ← ColorData (frozen dataclass) + ColorModel (QObject/Signal)
├── views/
│ ├── main_window.py ← QMainWindow, tab assembly, status bar
│ ├── picker_tab.py ← Picker layout + wires canvas→model
│ └── converter_tab.py ← Converter layout + bidirectional parse/format
├── widgets/
│ ├── color_card.py ← Reusable card (label + swatch + value + copy btn)
│ └── image_canvas.py ← Image display, eyedropper cursor, pixel loupe
└── utils/
└── styles.py ← Global Qt stylesheet + palette tokens
| Concern | Approach |
|---|---|
| Single source of truth | ColorModel owns the color; views read/write through it |
| Observable state | ColorModel.color_changed Signal → all views react |
| No circular updates | _syncing / _updating guards prevent re-entrancy |
| Pure conversions | All math in color_model.py — no Qt dependency, fully unit-testable |
| Reusability | ColorCard is the same widget used in both tabs (editable flag) |
- Ecosystem:
colorsys(stdlib), easy to extend withcolour-science,colormath,numpy - PySide6: official Qt binding, LGPL, identical API to Qt C++ — no lock-in
- Rapid iteration: stylesheet changes, signal wiring, layout tweaks without recompilation
- Packaging:
pyinstaller/cx_Freezefor a standalone.exe/.appin one command
# 1. Create & activate a virtual environment
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS / Linux
# 2. Install dependencies
pip install -r requirements.txt
# 3. Run
python main.pyOpen the colorpick/ folder, select the .venv interpreter, then run main.py.
No additional build step needed.
| ID | Name | Format |
|---|---|---|
rgb |
RGB | rgb(255, 128, 0) |
hex |
HEX | #FF8000 |
hsl |
HSL | hsl(30.0, 100.0%, 50.0%) |
hsv |
HSV | hsv(30.0, 100.0%, 100.0%) |
lab |
CIE L*a*b* | lab(66.89, 38.77, 74.99) |
lch |
LCH | lch(66.89, 84.65, 62.6) |
oklab |
OKLab | oklab(0.7654, 0.0753, 0.1756) |
oklch |
OKLCH | oklch(0.7654, 0.1912, 66.8) |
Add a new color space (e.g. CMYK):
- Add
format_cmyk()toColorDataincolor_model.py - Add
"cmyk": ("CMYK", "Cyan · Magenta · Yellow · Key")toSPACE_METAincolor_card.py - Add a
_parsebranch for"cmyk"inconverter_tab.py
That's it — the card grid is driven by SPACE_META so the new card appears automatically.