31 不能用 / 会崩 / 静默失效
✅ 已验证
这一章是整本书最值钱的表之一。Krita 的大量 setter 不校验参数、不报错、静默失效,而且有几个会直接崩掉进程(C++ 层,没有 Python traceback)。
会崩
| 东西 | 行为 |
|---|---|
没有 view 时的 paint* | 段错误,无 traceback |
QT_QPA_PLATFORM=offscreen | Krita 6 启动即段错误,必须 Xvfb |
node.save() 对 vectorlayer | 段错误,进程直接死。用 composite 取像素 |
createFillLayer(..., "simplenoise", ...) | 段错误("gradient" / "pattern" 正常) |
| 撤销栈吃光内存 | OOM killer 干掉进程,一句话不留。每次 paint* 约 233 KB,清不掉 |
v5.1.0 的六个探针(FilterMask / ColorizeMask / Preset XML / Scratchpad / 交付 / Shape)没有新增会崩的东西——失败的那几样都是老实返回 False 或静默无效。
静默失效
| 东西 | 行为 | 怎么发现 |
|---|---|---|
doc.setSelection(Selection()) / sel.clear() | 「全不选」,之后每笔画出 0 px | 笔刷「突然全不工作」 |
setBlendingMode("任意字符串") | 原样读回,按 normal 合成 | 量合成结果 |
scaleImage(..., strategy="xyzzy") | 尺寸照改,插值未知 | 先 filterStrategies() 校验 |
setPaintingOpacity(255) | 饱和成 1.0 | 量峰值 alpha |
f) Bristles-5 Flat + opacity | 完全无视 | 同上 |
| mypaint preset 画 1px 点 | 什么都不留 | 数像素 |
setBrushSize(n) | 画出来 0.2n–0.93n | 量宽度 |
| transparency mask 挂 rootNode | 孤儿节点,无影响 | 挂目标图层下 |
group passthrough=True + clip | clip 失效 | 看 alpha |
选区对 filter.apply() | 不限制 | 整幅都变了 |
| 崩溃留下的 autosave | 之后每次运行卡住 | rm -f *autosave*.kra |
| 相对路径的环境变量 | cd 之后失效 | 先 realpath |
Document.setBatchmode(True) 对撤销栈 | 无效(291 vs 297 笔/秒,RSS 照涨) | — |
kritarc 的 undoStackLimit 对 paint* | 无效 | RSS 照涨到 18.6 GB |
filter.apply() 返回值 | 成功也 None | 自己查像素 |
pixelData() 读到过期数据 | 读一次结论可能相反 | s.settle() 读到稳定 |
createFilterMask(name, f, **node**) | 不限制范围,整幅都处理 | 量剖面,没有过渡带 |
Scratchpad.resize() / setGeometry() | 无效,一直是 640×480 | 先 show() 再 resize() |
改预定义笔尖 preset 的 diameter | 无效 | 量笔宽 |
Preset.fromXML(toXML()) 对 mypaint | 有损:14 px → 442 px | 往返后量笔宽 |
Shape.setTransformation | 是替换不是叠加,冲掉原摆放 | 写 T0 * QTransform().translate(...) |
| shape 的几何单位是 pt | 拿 px 问 shapeAtPosition 得 None | PT = 72 / doc.resolution() |
| 组的投影在 shape 挪走后留残影 | 大框重心被拖偏 | 判位移用 boundingBox() 或解析真值 |
ColorizeMask 忘了 setEditKeyStrokes(False) | 输出是 50% 混白的编辑预览 | 量色块颜色 |
不存在 / 没有
| 东西 | 替代 |
|---|---|
Krita.instance().createInfoObject() | from krita import InfoObject |
Node.setFilter() | FilterLayer 上有 |
| 创建 keyframe 的 API | 一帧一个 document 导 PNG 序列 |
| 清撤销栈的 API | 少调用(第 19 章) |
createNode(..., "grouplayer") 的 setPassThroughMode | 用 createGroupLayer |
node.setLayerStyleFromAsl | 喂不进去:手写 PSD 描述符 XML 返回 False(XML 合法,是解析出的样式数 ≠ 1),layerStyleToAsl() 在没设样式时返回空串拿不到骨架,本机 asl/、layerstyles/ 和四个 bundle 里一个 .asl 都没有 |
Scratchpad 上的落笔 | 没有。只有 fill* / loadScratchpadImage;paintEngine / paintEvent / paintingActive 是 QWidget 自带的 |
Palette.save() | 返回 False,不写盘;也没有 Document 级 palette API,进不了 .kra |
手写的 transform_params | TransformMask.fromXML 返回 False。读出厂 toXML() 骨架再改就 True |
ColorizeMask.initializeKeyStrokeColors 的文档 | api.kde.org 的方法表里没有它,只有源码有。少了这步 setKeyStrokePixelData 全返回 False |
判错过的
这些曾经被记成「不能用」,后来发现是测量错了:
| 曾记 | 真相 |
|---|---|
setInheritAlpha 不生效(v1.0.0) | 把 base/top 建在根节点下,根下有全不透明 Background,累积 alpha 处处 255。放进 group 就生效 |
| transparency mask 无影响(v1.0.0) | 挂错了位置 |
| erase blending mode 擦掉 2198 px | 读到过期像素。读到稳定后是 0 |
| filter 不受选区限制(v5.0.0) | 那是 apply() 的结论。createFilterMask(name, f, **Selection**) 受选区限制且带羽化,过渡带 ≈ 1.5 × feather(第 30 章) |
| ColorizeMask「算不出东西」 | 少调了 initializeKeyStrokeColors,keystroke 根本没建;补上之后三个区面积吻合 0.98 |
| shape「挪不到位」 | 量的框比形状小,挪出框外被截断;换成对着「挪过的解析真值」量,偏差 0.0861 |
它们的共同点:判据看错了对象。第 34 章。