UI 设计
这一页只讲样子、颜色、字体、呼吸——不讲任何逻辑。 想看 Qt 信号槽、事件路径、CMD 协议、扫描算法那些脑力东西,请去对应功能页。
Shadow CE 的界面是一次对 Cheat Engine 7.5 的精准复刻 + 一次深色重调。远看像 Win32 老工具,近看每一条边都是自绘的。
1. 整体设计理念
- 深 × 深 × 更深:三段式灰阶背景,越里面越黑;从表格的
#2a2a2a到状态栏的#1a1a1a,再到 console 面板的#0a0a0a——眼睛顺着颜色深浅走,不需要边框引导 - 密而不挤:所有控件默认 padding 2-4px,行高贴着字体走,信息密度极高;留白只留在模块之间,不留在控件里
- CE 的两个护身符:
- Win32 对话框的骨架——标题栏、左列表右面板、OK/Cancel 居中排、虚线黄色选中框
- Dark-mode 的皮——整个调色板从 CE 7.5 原版抠出来再整体降低亮度
- 无锯齿像素字:所有字体都设
NoAntialias + PreferFullHinting,像 MFC 老工具栏一样硬邦邦、对齐整齐 - 动效只做一种:120ms OutCubic 的边框颜色过渡,只在 checkbox / hover 上出现,别的地方一律零动画
- 跨平台视觉一致:app 强制
Fusionstyle,不用系统原生控件;保证 WSLg / Windows / macOS 外观完全同一套
2. 调色板
整个应用的颜色从 16 个 token 里出。改这张表 = 整个 UI 换肤。
背景分层(由深到浅)
| token | hex | 用途 |
|---|---|---|
bg_deep | #1a1a1a | 最深:状态栏、console 底 |
bg_base | #2a2a2a | 扫描结果表、地址表内容 |
bg_alt | #2a2a2a | 交替行(= base,保留 token 以便调) |
bg_window | #353535 | 窗口/对话框主体 |
bg_panel | #353535 | 右菜单/侧面板 |
bg_header | #454545 | 表头渐变 top |
bg_header2 | #3d3d3d | 表头渐变 bottom |
bg_hover | #5c5c5c | 表头 hover top |
bg_hover2 | #585858 | 表头 hover bottom |
bg_selected | #3a3a3a | 选中行 |
bg_pressed | #484848 | 按钮/表头按下 |
bg_checked | #383838 | 切换开关选中 |
边框
| token | hex | 用途 |
|---|---|---|
border | #3a3a3a | 默认边框(= 选中背景,融入 UI) |
border_light | #9b9b9b | 输入框非 focus 边 |
border_hover | #555 | hover 边框 |
border_focus | #c8c8c8 | 输入框 focus / hover 高亮边 |
文本
| token | hex | 用途 |
|---|---|---|
fg | #f5f5f5 | 主文本(几乎全部文字) |
fg_dim | #f5f5f5 | 按钮文本(与 fg 同——保留 token 以便分离) |
fg_muted | #f5f5f5 | 次要标签 |
fg_disabled | #555 | 禁用态 |
fg_accent | #8cf | 青色强调(选中进程名) |
选中与强调
| token | hex | 用途 |
|---|---|---|
sel_bg | #264f78 | 选中底(CE 蓝) |
sel_fg | #ffffff | 选中文字 |
highlight | #0078d7 | 全局强调蓝(focus / 下拉高亮) |
滚动条
| token | hex | 用途 |
|---|---|---|
scroll_bg | #171717 | 滚动条轨道 |
scroll_handle | #959595 | 滑块 |
scroll_hover | #959595 | 滑块 hover |
Memory View 专属调色板
一套完全独立的配色,只用于 hex / disasm 视图内部的语法着色:
| 元素 | hex |
|---|---|
| mnemonic | #ffffff |
| branch mnemonic | #ffdd66 |
| register | #C1000D |
| immediate | #007fff |
| symbol / string ref | #008000 |
| comment | #666666 |
| hex normal / zero / changed / static | #ffffff / #444444 / #ff6666 / #008000 |
| ASCII 可打印 / 点 | #008000 / #444444 |
| 无条件 / 条件 / call 跳转箭头 | #008000 / #cc4444 / #ccaa44 |
| 编辑态背景 / 文字 | #3060a0 / #ffffff |
| 光标行 | #ff3333 |
五种颜色的节奏:黑底 + 白骨 + 绿字符串 + 蓝立即数 + 红寄存器。像极了早期 OllyDbg。
3. 字体三套
全局就两种角色:UI 字体(标签、按钮、菜单)和 Mono 字体(表格、十六进制、反汇编)。
默认值
| 角色 | family | 大小 | 用处 |
|---|---|---|---|
| UI | Segoe UI | 10px | 所有标签、按钮文字、对话框 |
| Mono | DejaVu Sans Mono | 9px | 结果表、地址表、hex view、disasm view |
| Header | Segoe UI | 9px | 表格列头 |
内置字体包
为了在 Linux / WSLg 下长得一样,字体文件被打包进 repo:
DejaVuSansMono.ttf DejaVuSansMono-Bold.ttf
consola.ttf consolab.ttf
cour.ttf courbd.ttf
segoeui.ttf segoeuib.ttf
tahoma.ttf tahomabd.ttf启动时一次性注册进 QFontDatabase。
三个用户可切换的 preset
在 Settings → 显示里切:
| preset 名 | mono | UI |
|---|---|---|
| CE Classic (Tahoma + Courier New) | Courier New | Tahoma |
| Consolas + Segoe UI | Consolas | Segoe UI |
| DejaVu Sans Mono | DejaVu Sans Mono | DejaVu Sans Mono |
第一个是怀旧 CE 原汁原味,第二个是现代 Windows 舒服版,第三个是Linux/开源纯净。
渲染参数
所有字体对象都强制:
setStyleStrategy(NoAntialias)setHintingPreference(PreferFullHinting)
结果是像素对齐的硬边字体——像 Vista 之前的 MFC 工具一样硬朗、不发糊。
4. 主窗口一眼看
┌─────────────────────────────────────────────────────────────┐
│ [ icon Select Process ] process name ≡ ⚙│ ← top bar
├─────────────────────────────────────────────────────────────┤
│ ▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱ 10px hairline progress
│ Found: 1,234 │ ← found label
├──────────────────────────────────────────┬──────────────────┤
│ │ [First][Next] │
│ Address Value Prev First │ [Undo] │
│ ────────────────────────────────── │ │
│ 0x7ff12345... 100 ... ... │ Value: [____] │
│ 0x7ff1234b... 99 ←红 100 100 │ □ hex │
│ │ │
│ (扫描结果 virtual model) │ Scan: [Exact ▾] │
│ │ Type: [4 Byte▾] │
│ │ │
│ │ ┌─Options──────┐ │
│ │ │ Region [▾] │ │
│ │ │ Start: ... │ │
│ │ │ Stop: ... │ │
│ │ │ ☑ writable │ │
│ │ │ ☐ executable │ │
│ │ │ ☑ fast [4 ↕] │ │
│ │ └──────────────┘ │
├──────────────────────────────────────────┴──────────────────┤
│ [ Memory View ] ⛔(center) │ ← mid bar 28px
│ │
│ ☐ Description Address Type Value │
│ ─────────────────────────────────────────────── │
│ ☑ health 0x7ff... 4B 100 │ ← address list
│ ☑ armor 0x7ff... 4B 50 │
│ │
│ [Add address] │
└─────────────────────────────────────────────────────────────┘- 默认尺寸:
1050 × 780 - 外边距:0,内容区再 2px
- 分割器:水平方向左结果右选项,垂直方向上半结果下半地址表,比例
2:1,初始400:200 - 无边框 QFrame——靠背景色分区,不靠线
顶栏(约 34px 高)
- 左:
[openprocess.png 图标] Select Process按钮(普通 QPushButton,边框#9b9b9b) - 中:当前进程名 label,深色灰底,默认浅灰字
#f5f5f5 - 右:两个 28×28 的透明方形图标按钮
≡(hamburger,U+2261)= Workspace 面板开关⚙(gear,U+2699)= Settings- 透明底、
#5551px 边框,hover 变#3a3a3a底 + 白字
进度条(10px hairline)
- 整体高度极薄,无文字
- 边框
#3a3a3a1px,填充色#555——扫描时像一根灰光带从左爬到右 - max=1000(千分制),避免浮点抖动
结果表(左大块)
QTableView+ 虚拟模型(随便几百万行都不卡)- 无 gridline
- 字体 DejaVu Sans Mono 9px,行高 = 字体 metrics + 4px
- 四列比例:
Address 30% | Value 30% | Previous 20% | First 20% - 表头渐变
#454545 → #3d3d3d,hover 亮成#5c5c5c → #585858 - 实时对比着色:
Value列和上次不同 → 文字红#ff0000;其他行默认白字 - hover 高亮:被鼠标悬停的行整行淡蓝
#263440 - 选中:自绘
#223E55底 +#0078D41px frame(顶/底两横 + 首尾列的左/右竖)
右侧面板(320px 固定宽)
从上往下:
- 三按钮行:
[First Scan] [Next Scan]靠左 +[Undo]靠右(CeButton 统一 75×20) - Value 区:
- 左侧
□ hex小 checkbox(CeCheckBox,布局反向——text 在左) - 右侧 label
Value:+QLineEdit - 切换 scan type 时空间保留——不会跳
- 左侧
- Scan Type 行:label + 下拉按钮(占满剩余宽)
- Value Type 行:label + 下拉按钮,默认
4 Bytes - Memory Scan Options 灰框 GroupBox:
- Region 下拉
- Start / Stop:label +
QLineEdit,里面字体强制DejaVu Sans Mono 10px等宽显示地址 ☑ writable(默认勾) /☐ executable☑ fast_scan [spinbox=4]对齐字节步长
中分条(28px 高)
- 背景
bg_window#353535 - 左对齐
[Memory View]按钮 - 正中心绝对定位一颗 26×26 的
⛔红色图标按钮(stop.png)- 作用:清空整个地址列表(危险操作给你放正中央)
- 透明底 +
#9191911px 边框 + hover#444
地址表(下半)
- 5 列:
Active [checkbox] | Description | Address | Type | Value Active列固定 40px 宽;其余按比例:description 35% / address 20% / type 13% / value stretch- 自绘 checkbox
- 支持行内编辑(
Description列双击改名) - 支持 drag 排序 + 从结果表 drop 过来新增
- 多选、右键菜单
- 选中:
#2A82DA蓝底 + 1px 虚线黄边#e0c030
Workspace 悬浮面板(从左滑出)
- 触发:点顶栏
≡按钮 - 尺寸:380 宽 × 窗口剩余高(从顶 34px 开始)
- 底
#2b2b2b,右边一条 1px#444描边——像一张卡从侧边滑出贴着主窗口 - 标题 Recent 加粗白字
- 表格:无行头、无列头,图标列 28px 固定、PID 55px、描述 160px、type stretch
- 行高 28px,每行一张 20×20 app icon
- item hover
#5c5c5c背景,pressed#9b9b9b - 点击窗口任意其他地方 → 自动收回
Esc也可以收
5. 按钮的三种口吻
CeButton ——“正事儿按钮”
- 固定 75×20——CE 原版尺寸
- 背景
#333333、边框#9b9b9b1px、圆角 4px - 文字
#f5f5f5,字号 9px - hover:背景
#454545+ 边框#c8c8c8(变白) - pressed:整个底变成边框色
#9b9b9b——视觉反转 - disabled:
#2a2a2a底 +#555字
用在:First Scan / Next Scan / Undo / Open / Cancel / Refresh / Console / Settings / Save / Load 这些能触发操作的地方。
通用 QPushButton ——“次要按钮”
- 不定宽,padding 2×8px、圆角 4px
- 底
#2a2a2a - 边框
#9b9b9b1px - hover 底
#585858,pressed 底#9b9b9b - checked 态
#383838+#888边 - 用在:
Select Process / Memory View / Add Address这些”常驻”按钮
图标按钮 ——“透明方形”
- 固定 28×28 或 26×26
- 透明底 + 1px 暗灰边
- 只显图标/符号:
≡/⚙/⛔ - hover 底
#3a3a3a+ 文字变白——hover 前像”关闭态”,hover 后像”激活”
6. 输入框和下拉
QLineEdit / QSpinBox
- 底
#2a2a2a、文字#f5f5f5、边框#9b9b9b1px - 圆角 1px(几乎方——CE 味)
- padding 1×3px,内部塞满
- hover / focus:边框变白
#c8c8c8——安静的边框呼吸 - disabled:底
#2a2a2a不变、文字和边框变#555和#3a3a3a——几乎”隐没进背景”
DropdownButton —— 自造的 ComboBox 替代品
- 外观上就是 QPushButton
- 左对齐文字,左 padding 4px、右 padding 16px(留给想象中的箭头——但其实没画箭头)
- 点击弹出 QMenu 精确贴在按钮下沿,宽度至少等于按钮宽
- 菜单样式:
- 底
#353535(window 色) - 1px 边框
#0078d7(highlight 蓝) - padding 2px,item padding
3×20×3×8px - 字号 11px
- 选中项:
#0078d7蓝底 + 1px 虚线黄边#e0c030——和表格的选中虚线是一对
- 底
7. 表格通用装扮
- 全程不画分割线,靠行高和颜色撑秩序
- 行高 = Mono 字体 metrics + 4px padding
- 选中底色
#3a3a3a - 表头:
- 渐变
#454545 → #3d3d3d,底部 1px 边框#3a3a3a - 文字左对齐,字号 9px,粗细 normal(不加粗)
- min/max-height 都固定 15px——薄表头
- hover 时渐变整体变亮到
#5c5c5c → #585858 - pressed 整个变暗
#484848
- 渐变
- 列宽支持交互调整、最后一列自动拉伸
三个选中样式 Delegate(细节成精)
结果表选中
bg = #223E55(深蓝灰)
frame = #0078D4(CE 强调蓝)1px 实线
├ 顶边 & 底边:每个 cell 都画
└ 左边 / 右边:只在首列 / 末列画地址列表选中
bg = #2A82DA(亮蓝)
frame = #e0c030(黄)1px 虚线
文字 #f5f5f5
第 0 列(Active):14×14 自绘 checkbox 在 cell 左 6px 居中全局款(进程列表 / 应用树)
- 同款蓝底 + 虚线黄边
- 自动识别 decoration icon(图标列),绘完图标再画文字
三个 delegate 的虚线黄边 #e0c030 = 整个应用最一致的视觉签名。
8. CeCheckBox ——“会呼吸的小方框”
- 尺寸 13×13
- 默认:1px 边框
#8e8e8e(暗灰) - hover:120ms OutCubic 动画把边框色过渡到
#2a75a5(蓝灰) - 按下(未释放):120ms 回到
#8e8e8e - 释放在盒内(= 真点中):120ms 再到
#2a75a5 - 勾上时自绘”✓”:
#8e8e8e1.5px 抗锯齿线- 短下坡 → 长上坡,CE 原版一样的手写勾
- 文字放盒子右侧 4px 间距,
#f5f5f5白字
整个应用里只有 checkbox 是”活的”。按钮不呼吸、输入框不呼吸、下拉不呼吸、表格不呼吸——只有 checkbox 眨眼。
9. 滚动条 ——“害羞的滑块”
- 16px 宽(粗一点以便点)
- 轨道
#171717(几乎黑) - 滑块
#959595+ 3px 圆角,上下各留 20px 空白 + 左右各 5px 内缩 - 默认状态下:箭头按钮完全隐形
- 鼠标一进入滚动条:箭头冒出来(SVG 从
arrow_up_dim.svg到arrow_up.svg) - 离开:箭头又缩回去
- 效果:滚动条很克制,只在你靠近时才展露功能
SVG 图标的双态
| 状态 | 文件 |
|---|---|
| 静默 | arrow_{up,down,left,right}_dim.svg 9×9 |
| 激活 | arrow_{up,down,left,right}.svg 10×10 |
大了 1px,hover 瞬间像点亮了灯泡。
10. 菜单、Tab、GroupBox
QMenu(右键菜单、下拉菜单)
- 底
#2a2a2a,边框#a0a0a01px - padding 2px,item padding
3×20×3×8px - 字号 9px(比按钮更小,因为菜单要密)
- hover item 底
#424242+ 白字 - 分隔线:1px 高
#3a3a3a,左右各 4px margin
QTabWidget / QTabBar
- Tab 本体
#3E3E3E底,非激活字色#aaa - 1px 边框
#3a3a3a,底边去掉(和 pane 连一起) - hover:底
#6a6a6a+ 字变白 - 激活:底
#5d5d5d+ 字变白 + padding 变大一点(3×26px)+ margin-top 归零(“抬高一格”视觉效果)
QGroupBox
- 边框 1px
#3a3a3a,圆角 2px(几乎方) - 标题文字
#999(比正文略暗) - 标题嵌在顶边框上,左 6px、两侧各 3px padding,像传统 Win32 GroupBox 的缺口标题
QProgressBar
- 1px 边框
#3a3a3a,圆角 1px - 居中字色
#aaa,字号 8px - chunk 填充
#555(不亮不刺眼)
11. 对话框画廊
Connect Window(进程选择)
- 尺寸 380×420,标题
Process List - 底
#353535(bg_window) - 三栏可折叠布局:
- 左 console 面板:宽 0(隐藏),展开变 200px,深黑
#1a1a1a+ 右边 1px#333- 里面日志 TextEdit,
#0a0a0a底 +#ccc字 + Mono 8px
- 里面日志 TextEdit,
- 中 center:搜索框(占位文字
Search... (Ctrl+F))+ GlowBar(3px 高霓虹条) + Applications/Processes 两个 Tab + 底部三组竖排按钮 - 右 settings 面板:宽 0(隐藏),展开变 150px,也是
#1a1a1a+ 左 1px#333- Host / Port 两行输入
- 左 console 面板:宽 0(隐藏),展开变 200px,深黑
- 展开左 console / 右 settings 按钮是 checkable——点它们窗口会向两侧”长出”相应宽度,给人一种”抽屉拉开”的感觉
GlowBar(3px 进度霓虹)
- 自绘纯色矩形从左到右画进度
- 默认色
QColor(0, 200, 80)(荧光绿) - paint 条件:
0 < value < 1.0才画——完成(=1.0)时条消失 - 连接成功后变另一个色用来讲不同状态
Application/Process 列表
- 4 列:checkbox-width + PID(45) + Package(160) + Name(stretch)
- 头部隐藏,图标 16×16
- 字号 UI 8px(更密),选中统一蓝底虚线黄边
Settings Dialog
- 640×420,标题
Settings - 左右分区:
- 左:120px 分类列表,5 个分类(General / Scan / Display / Timers / Debugger)
- 右:
QStackedWidget配合,切换 page
- 右侧容器主色
#2c2c2c(比 window 更深一点,让设置区”凹进去”) - 底部:
QFrame HLine分隔线(#333) - 底部按钮:
[OK] [Cancel]各 80px 宽,居中排成一行 - 每个控件 valueChanged / toggled 都是实时应用——不需要点 OK 才生效
AddAddress Dialog
- 深底常规,标题根据模式变
Add Address/Edit Address - 关键细节:辅助文本色
#6688aa(蓝灰)—— 用在”base + offset 解析出的实际地址”旁边- 字号 9px,比主体小一号
- 整体像一个迷你的两列表单
HwbpWindow(独立窗口)
- 标题动态:
Opcodes Access/Opcodes Read/Opcodes Write根据 bp_type 切换 - 独立窗,不 modal
- 里面是命中日志表 + 控制条,视觉语言和主窗口完全一致(同一套 THEME / 同一套字体 / 同一套 delegate)
Ptrscan Settings Dialog / Results Window
- 两个分开的 QDialog
- Settings 标题
Pointer Scan Settings(表单式) - Results 标题动态
Pointer Scan Results — N chains - Results 窗带自己的滚动/刷新、但主题一致,不是另一套皮
12. 图标资源
位于 client/icons/。
| 文件 | 格式 | 尺寸 | 用途 |
|---|---|---|---|
celogo.png | PNG | 64×64 | 窗口 icon、任务栏 icon |
openprocess.png | PNG | 16×16 | Select Process 按钮 |
stop.png | PNG | 22×22 | 清空地址列表的 ⛔ 按钮 |
advanced.svg | SVG | — | 高级功能图标 |
question.svg | SVG | — | 帮助 / 提示 |
arrow_*.svg + arrow_*_dim.svg | SVG | 9-10px | 滚动条箭头双态 |
arrow_down_right.svg | SVG | — | 嵌套/展开指示 |
PNG 用于需要透明通道和丰富色彩的场合,SVG 用于黑白小图标(可双态缩放)。
Windows 下的 taskbar icon 通过 SetCurrentProcessExplicitAppUserModelID 显式绑定,不会被 Python 默认 icon 顶掉。
13. 多语言 ——“纯换字,不换骨”
- 所有文字走翻译函数
tr("key") - Settings → General → 语言下拉切换,不需要重启
- 切换后:所有静态 label / button 文字重扫一遍
- Dropdown 的 items 也会重新填入对应新语言
- 布局不会变化——长字母短汉字都靠 splitter 和 stretch 吸收
支持语言:中文 / English。
14. 热重载脚本
开发时改样式表 / THEME / 主窗口布局,不用关应用重启——
运行 hot_reload.sh 后:
- 监听
client/*.py改动 - 应用收到信号后重建 stylesheet + 全局应用
- 调色板 / 字号 / QSS 几秒内看到变化,不丢当前扫描状态
15. DPI & 跨平台
- 启动时设
HighDpiScaleFactorRoundingPolicy.PassThrough——不做整数倍舍入,像素精确 - WSLg(WSL2 图形):环境变量
GALLIUM_DRIVER=d3d12强制走 D3D12 GPU 后端,不走 CPUllvmpipe——大表滚动流畅度直接翻倍 - Windows:AppUserModelID 固定
s1lently.shadow_ce,taskbar 图标就是 celogo - App 强制
Fusionstyle + 深色 palette——永远不继承系统 GTK / Win32 原生控件样式
16. 视觉签名清单
回头看全局,几个反复出现的”设计指纹”:
- 1px 虚线黄边
#e0c030:每个列表/表格/下拉菜单的选中项都有 #0078d7CE 强调蓝:progress focus、下拉菜单描边、结果表选中 frame- 圆角梯度:输入框 1px、按钮 4px、GroupBox 2px、滚动条 handle 3px——越操作频繁越圆
- 字号梯度:table 9px < UI 10px < 主文本 10px < 标题 12px < 大号 14px;调一个 token 整套跟着长大
- hover 不亮文字:文字永远
#f5f5f5,只背景响应 hover——文字从不抢视觉 - “透明 QFrame”:所有分区靠背景色区分,没有可见的分隔线——视觉极其干净
17. 最后:一句话体会
Shadow CE 的 UI 语言是**“把 Cheat Engine 7.5 剥了皮拿深色腻子糊回去”**——骨架(布局、控件尺寸、选中框风格、菜单行为)完全保留,颜色换成一套深夜友好的 16 色表,字体换成像素硬朗的 Segoe UI + DejaVu Mono,动效只留 120ms 的 checkbox 呼吸,其余全是静的。看起来像”修过的老工具”,但每一根虚线、每一个边框、每一个 padding 都是自己手写了 500+ 行 QSS + 300+ 行 QPainter 画出来的。