官方教程 §2.2 画布容器控件 描述不完整(可能有误导性)
Documentation Link
https://maliang-docs.netlify.app/3.0/tutorials/chapter_02/2/
Problem
在 §2.1.2 隐藏/显示来切换页面 中提到
如果窗口这个时候已经放大了,但你还是使用之前的方式去显示画布,就会导致画布看起来变小了。... ... 很显然,上面的示例就会导致画布没有同步缩放。应该修改为如下代码: ... ...此方法仅对 Place 布局有效。
根据测试,画面缩放问题不仅在 Place 布局中会出现,在 子控件 中也有同样的表现,以下是测试过程
先展示正确做法(本段代码主体内容引用自 §2.1.2 例程)
from itertools import count
import maliang
root = maliang.Tk()
root.center()
cv = maliang.Canvas(bg="orange", auto_update=False, auto_zoom=True, free_anchor=True)
cv.place(width=1280, height=720)
cnt = count()
maliang.Text(cv, (640, 360), text=next(cnt))
def func() -> None:
cv.place(width=1280, height=720)
maliang.Text(cv, (640, 360), text=next(cnt))
cv.update()
cv.zoom()
root.after(3000, func)
root.after(3000, func)
root.mainloop()
然后是错误做法
def func() -> None:
maliang.Text(cv, (640, 360), text=next(cnt))
root.after(3000, func)
测试结果表明,在父控件显示期间增加新的子控件也无法正确处理缩放比问题,这种现象可能是一个bug。目前尚未在嵌套画布中测试,也就是说很可能 §2.4 嵌套画布 部分也要同步添加相应的介绍
Suggested improvement
目前的应急处理方案就是如上文中说的一样,每次添加子控件前先将父控件改回原来的尺寸,然后添加子控件,最后重新处理缩放比。此方案目前有两个缺陷:
- 这可能会带来额外的性能开销
- 每次添加子控件都会使父控件闪烁,这可能与 issue102 #102 中提到的闪烁问题相似
Contact Details
Code of Conduct
- [x] I agree to follow this project's Code of Conduct
再次测试表明,上面的做法仍然不是正确的(只能解决 Text 控件,对于 Label 控件还是无法正确处理缩放比问题)。最稳妥的方案应该 是这样:
cv.place(width=1280, height=720)
cv.update()
cv.zoom()
maliang.Label(cv, (640, 360), (64, 64), text=next(cnt))
cv.update()
cv.zoom()
其中 Label 前的 zoom 用来确保 Label 形状缩放比不变,Label 后的 zoom 用来确保 Label 位置缩放比不变。
因此每次添加新控件都会使得屏幕闪烁两次,对于性能开销和实际体验的影响都很大。可能需要新的 Feature 解决这一问题
在程序启动后在运行时动态增加控件需要调用控件的方法 zoom 来自动调整缩放,这会将控件自动缩放到合适的大小。并不需要对画布做出任何更改。
这个不是 bug,而是文档中没有提到这一点,后续更新时会对此进行补充
已在仓库 https://github.com/Xiaokang2022/maliang-docs 的提交 https://github.com/Xiaokang2022/maliang-docs/commit/e715c1953f3a84934bae8eb34d7e363a455d4a4a 中完善该部分文档的内容,将在下个版本发布时同步更新。