Skip to Content

UI 设计

这一页只讲样子、颜色、字体、呼吸——不讲任何逻辑。 想看 Qt 信号槽、事件路径、CMD 协议、扫描算法那些脑力东西,请去对应功能页。

Shadow CE 的界面是一次对 Cheat Engine 7.5 的精准复刻 + 一次深色重调。远看像 Win32 老工具,近看每一条边都是自绘的。


1. 整体设计理念

  • 深 × 深 × 更深:三段式灰阶背景,越里面越黑;从表格的 #2a2a2a 到状态栏的 #1a1a1a,再到 console 面板的 #0a0a0a——眼睛顺着颜色深浅走,不需要边框引导
  • 密而不挤:所有控件默认 padding 2-4px,行高贴着字体走,信息密度极高;留白只留在模块之间,不留在控件里
  • CE 的两个护身符
    1. Win32 对话框的骨架——标题栏、左列表右面板、OK/Cancel 居中排、虚线黄色选中框
    2. Dark-mode 的皮——整个调色板从 CE 7.5 原版抠出来再整体降低亮度
  • 无锯齿像素字:所有字体都设 NoAntialias + PreferFullHinting,像 MFC 老工具栏一样硬邦邦、对齐整齐
  • 动效只做一种:120ms OutCubic 的边框颜色过渡,只在 checkbox / hover 上出现,别的地方一律零动画
  • 跨平台视觉一致:app 强制 Fusion style,不用系统原生控件;保证 WSLg / Windows / macOS 外观完全同一套

2. 调色板

整个应用的颜色从 16 个 token 里出。改这张表 = 整个 UI 换肤。

背景分层(由深到浅)

tokenhex用途
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切换开关选中

边框

tokenhex用途
border#3a3a3a默认边框(= 选中背景,融入 UI)
border_light#9b9b9b输入框非 focus 边
border_hover#555hover 边框
border_focus#c8c8c8输入框 focus / hover 高亮边

文本

tokenhex用途
fg#f5f5f5主文本(几乎全部文字)
fg_dim#f5f5f5按钮文本(与 fg 同——保留 token 以便分离)
fg_muted#f5f5f5次要标签
fg_disabled#555禁用态
fg_accent#8cf青色强调(选中进程名)

选中与强调

tokenhex用途
sel_bg#264f78选中底(CE 蓝)
sel_fg#ffffff选中文字
highlight#0078d7全局强调蓝(focus / 下拉高亮)

滚动条

tokenhex用途
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大小用处
UISegoe UI10px所有标签、按钮文字、对话框
MonoDejaVu Sans Mono9px结果表、地址表、hex view、disasm view
HeaderSegoe UI9px表格列头

内置字体包

为了在 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 名monoUI
CE Classic (Tahoma + Courier New)Courier NewTahoma
Consolas + Segoe UIConsolasSegoe UI
DejaVu Sans MonoDejaVu Sans MonoDejaVu 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
    • 透明底、#555 1px 边框,hover 变 #3a3a3a 底 + 白字

进度条(10px hairline)

  • 整体高度极薄,无文字
  • 边框 #3a3a3a 1px,填充色 #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 底 + #0078D4 1px frame(顶/底两横 + 首尾列的左/右竖)

右侧面板(320px 固定宽)

从上往下:

  1. 三按钮行:[First Scan] [Next Scan] 靠左 + [Undo] 靠右(CeButton 统一 75×20)
  2. Value 区
    • 左侧 □ hex 小 checkbox(CeCheckBox,布局反向——text 在左)
    • 右侧 label Value: + QLineEdit
    • 切换 scan type 时空间保留——不会跳
  3. Scan Type 行:label + 下拉按钮(占满剩余宽)
  4. Value Type 行:label + 下拉按钮,默认 4 Bytes
  5. 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
    • 作用:清空整个地址列表(危险操作给你放正中央)
    • 透明底 + #919191 1px 边框 + 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、边框 #9b9b9b 1px、圆角 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
  • 边框 #9b9b9b 1px
  • 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、边框 #9b9b9b 1px
  • 圆角 1px(几乎方——CE 味)
  • padding 1×3px,内部塞满
  • hover / focus:边框变白 #c8c8c8——安静的边框呼吸
  • disabled:底 #2a2a2a 不变、文字和边框变 #555#3a3a3a——几乎”隐没进背景”
  • 外观上就是 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
  • 勾上时自绘”✓”:
    • #8e8e8e 1.5px 抗锯齿线
    • 短下坡 → 长上坡,CE 原版一样的手写勾
  • 文字放盒子右侧 4px 间距,#f5f5f5 白字

整个应用里只有 checkbox 是”活的”。按钮不呼吸、输入框不呼吸、下拉不呼吸、表格不呼吸——只有 checkbox 眨眼。


9. 滚动条 ——“害羞的滑块”

  • 16px 宽(粗一点以便点)
  • 轨道 #171717(几乎黑)
  • 滑块 #959595 + 3px 圆角,上下各留 20px 空白 + 左右各 5px 内缩
  • 默认状态下:箭头按钮完全隐形
  • 鼠标一进入滚动条:箭头冒出来(SVG 从 arrow_up_dim.svgarrow_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,边框 #a0a0a0 1px
  • 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
    • 中 center:搜索框(占位文字 Search... (Ctrl+F))+ GlowBar(3px 高霓虹条) + Applications/Processes 两个 Tab + 底部三组竖排按钮
    • 右 settings 面板:宽 0(隐藏),展开变 150px,也是 #1a1a1a + 左 1px #333
      • Host / Port 两行输入
  • 展开左 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.pngPNG64×64窗口 icon、任务栏 icon
openprocess.pngPNG16×16Select Process 按钮
stop.pngPNG22×22清空地址列表的 ⛔ 按钮
advanced.svgSVG高级功能图标
question.svgSVG帮助 / 提示
arrow_*.svg + arrow_*_dim.svgSVG9-10px滚动条箭头双态
arrow_down_right.svgSVG嵌套/展开指示

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 后端,不走 CPU llvmpipe——大表滚动流畅度直接翻倍
  • Windows:AppUserModelID 固定 s1lently.shadow_ce,taskbar 图标就是 celogo
  • App 强制 Fusion style + 深色 palette——永远不继承系统 GTK / Win32 原生控件样式

16. 视觉签名清单

回头看全局,几个反复出现的”设计指纹”:

  • 1px 虚线黄边 #e0c030:每个列表/表格/下拉菜单的选中项都有
  • #0078d7 CE 强调蓝: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 画出来的。

Last updated on