用 MFC 写 GUI 程序是一种什么样的体验?

本文来自知乎问题:MFC、WTL、WPF、wxWidgets、Qt、GTK 各有什么特点?

感觉我说了太多 Qt 的事情了,今天只说一下 MFC ,到底过时在哪里,都在说 “MFC 就是 xxx” 类似的话,我来补充点细节,增加点感性认识,到底 MFC 过时在哪里?想要用好 MFC 可以怎么办?

虽然 MFC 也有 DIALOG 的设计器,似乎可以拖一下控件,做个 hello world, 计算器之类的好像也很简单,但是稍微复杂那么一点就麻烦了,比如布局,MFC 里的控件只能设置绝对坐标和大小,那么如果你的窗口扩大或者缩小了,想自动改变内部特定控件的大小和位置怎么办?比如 C# 里随便设置一下各个控件的 docking 和 anchor 就能:

C# 里给控件设置 docking/anchor:窗口变大变小后就能自动调整控件的位置和大小

就能让某些控件随窗口变大而移动,某些控件随窗口变大而变大,而某些控件不变,这在任何 GUI 库里都是最基础的功能,都可以在设计器里点两下就做到的事情,MFC 却需要重载 WM_SIZE, WM_SIZING 消息来自己写代码每次手工计算所有控件的新坐标和大小,想写的通用点,还得上千行的代码,枚举所有子控件,根据额外信息重新计算位置大小,虽然 2015 的 MFC 里加了一个半成品的布局信息,但是基本没用,你在 MFC 的设计器里拖控件,都是写死坐标和大小的。(点击 Read more 展开)

Continue reading

Loading

Posted in 编程技术 | Tagged | 1 Comment

怎么样打包 pyqt 应用才是最佳方案?

早先看一堆人说 PyQt 打包麻烦,部署困难的,打出来的包大(几十兆起步),而且启动贼慢,其实 Python+PyQt 打包非常容易,根本不需要用什么 PyInstaller,我手工打包出来的纯 Python 环境只有 5MB,加上 PyQt 也才 14MB。

很多人用 PyInstaller 喜欢加一个 -F 参数,打包成一个单文件:

这样的单文件看起来似乎很爽,其实他们不知道,这其实是一个自解压程序,每次运行时需要把自己解压到 temp 目录,然后再去用实际的方式运行一遍解压出来的东西:

Process Explorer 把雷达图标拖动到 pyqt_hello.exe 的窗口上,可以看到有两个 pyqt_hello.exe 的文件,外面那个是你打包出来的,里面那个才是真正的程序(虽然可执行都是一个),看看它下面依赖的 python310.dll 是在哪里?这不就是一个临时解压出来的目录么:

看到没?这就是你 PyInstaller 打包出来的 30MB 的程序,每次运行都要临时解压出 71MB 的文件,运行完又删除了,那么如果打包出来的可执行有 100MB,每次运行都要释放出 200-300 MB 的东西出来,所以为什么 PyInstaller 出来的单文件运行那么慢的原因除了每次要解压外,还有杀毒软件碰到新的二进制都要扫描一遍,你每次新增一堆 .dll , .pyd, .exe,每次都要扫描,不慢可能么?

其实 PyInstaller 如果不打包成单文件可执行(-F 参数),用起来问题不大,唯一不足有两个,首先是很多动态库其实我没用比如上面的 socket, ssl, QtQuick 等,但都被打包的时候打进去了,大小会偏大;其次是目录看起来很乱,上百个文件一个目录,找主程序都找不到。

正确的打包姿势

当然是手工打包,现在 Python 3.5 以后,官方都会发布一个嵌入式 Python 包:

链接在这里:Python Release Python 3.8.10

(点击 more/continue 继续)

Continue reading

Loading

Posted in 编程技术 | Tagged , | 1 Comment

桌面开发用 Tkinter/wxPython/PyQt 哪个好?

Python 有很多 GUI 框架,比如著名的 Tkinter,wxPython 和 PyQt,那么想用 Python 开发桌面软件的话选哪个更好呢?作为三个都用过的人先给个结论,不用纠结,直接选 PyQt 即可。

很多人说 Tkinter 简单无依赖,没错,但这就是 tkinter 唯一的仅存的优点了,但是请大家注意,Tkinter 的这个 “简单”,是指 “功能少和效果单一”,不是写程序简单明了,真正写起程序来还是 PyQt 最简单清晰。

有些东西你学出来就过时了,比如 “算盘”,比如 Tkinter 和 wxPython;而有的东西你学会了,即便不吃这碗饭,不靠它涨工资,也能在今后一二十年持续受益,比如练习打字速度,比如背单词,比如学习 PyQt。

对于桌面开发,天下武功那么多,PyQt 既是最正统的门派,同时又是一系列综合技术的组合,它近可以同 C++ Qt 无缝整合,解决性能相关的东西;退,又有基于 chromium 的 QtWebEngine ,能在适合跑页面的部分用 html/js 来写页面,并和 python 双向调用,实现类似 cef/Electron 的效果,但是 Electron 这类单一解决方案就只能用 web 技术,想反过来同 native 界面混合开发,基本就傻了,碰到性能问题又不能像 PyQt 那样可以无缝切换 C++ Qt,所以庞然大物 Electron 只适合呆在自己的舒适区。

往左,QtWidgets 可以和传统 C# 的 WinForm pk,往右,Qt-Quick 可以同 WPF/XAML 看齐,因此你可以把 PyQt/Qt 看成一系列界面解决方案的 “超集”,所以学习 PyQt 你学会的是综合格斗术,是名门正派的内功心法,而不是某方向单一的方案,比如 “螳螂拳”。

PyQt 就是一扇门,它通往的是最专业的桌面解决方案的世界。

看了不少挺 Tkinter 的,他们用 Tkinter 用的都太浅了,知乎上有个最高赞用 Tkinter 费力拙略地模仿了个背单词的 anki,也许他不知道,他所模仿的 anki 其实本身就是用 PyQt 开发的。

真的用的深的只有这个回答:
为何很多Python开发者写GUI不用Tkinter,而要选择PyQt和wxPython或其他?

我曾经用 Tkinter 做过一些内部工具,比如给线上网络服务做的一个 RPC 调试终端:

当时我就是图别的同事使用时不用装其他库,结果写到后面,越做越后悔。

(点击 continue/more 继续)

Continue reading

Loading

Posted in 编程技术 | Tagged , | Leave a comment

我在命令行下学日语

同一个动作重复 300 遍,肌肉就会有记忆,重复 600 遍,脊柱就会有记忆,学完五十音图不熟练,经常遗忘或者要好几秒才想得起来一个怎么办?没关系,我做了个命令行下的小游戏 KanaQuiz 来帮助你记忆:

usage python3 kanaquiz.py <operation>
operations: 
    python3 kanaquiz.py {-h}     play hiragana only
    python3 kanaquiz.py {-k}     play katakana only
    python3 kanaquiz.py {-a}     play all kana quiz
    python3 kanaquiz.py {-d}     play dakuon quiz
    python3 kanaquiz.py {-t}     play trinity quiz
    python3 kanaquiz.py {-l}     list kanas with romaji
    python3 kanaquiz.py {-o}     list kanas only
    python3 kanaquiz.py {-q}     query performance history

首先使用 -l 参数来复习所有假名:

python3 kanaquiz.py -l

然后在终端中查看:

当你复习完了,可以用下面命令开始挑战:(点击 Read more 展开)

Continue reading

Loading

Posted in 随笔 | Tagged | Leave a comment

Vim2022:实时代码格式化

大部分 IDE/编辑器 都有代码格式化的功能或者插件,但都需要你主动触发格式化命令,而且每次写很多代码在保存的时候一次性格式化,总会有种不放心的感觉,需要跳过头去检查。

有没有可能让我一边写一边实时格式化呢?这样每次我都能看到最终的效果。

于是我写了个小脚本 vim-rt-format,再 INSERT 下面每次按回车就能自动格式化当前行:

有了这个东西以后,写代码爽多了,释放注意力,完全专注于 “编码”,再也不用为 “格式化”这个事情花费额外的精力,变量名和运算符之间无需加空格,直接回车就自动变成干净清爽的代码了,能自动识别语法元素,并且格式化的过程无需离开 INSERT 模式。

目前支持:Python, Lua, Javascript 几种语言,使用的话,只需要 Vim 支持 +python3 特性,且 Python 安装 autopep8 模块即可,配置如下:

" 使用 vim-plug 安装插件
Plug 'skywind3000/vim-rt-format'

" 默认在 INSERT 模式下按 ENTER 格式化当前代码行,将下面设置
" 成 1 的话,可以用 CTRL+ENTER 来格式化,ENTER 将保留原来的功能
let g:rtf_ctrl_enter = 0

" 离开 INSERT 模式的时候再格式化一次
let g:rtf_on_insert_leave = 1

行了,保存配置并重启 Vim,随便打开一个源代码开始编辑,就是这么简单。

你会忽然发现,天空变得更加晴朗,空气变得更加的清新,多么美好的一天啊。

项目主页:

https://github.com/skywind3000/vim-rt-format

Loading

Posted in 未分类 | Tagged | Leave a comment

如何在八叉树里寻找离某位置最近的点?

第一步:如果给定点 z 在八叉树包围盒内就从所属的最末端的子包围盒叶子节点开始,如果在八叉树外的话就从任意最靠近的叶子节点开始,先找一个最靠近 z 的候选点 A,如果叶子节点包围盒是空的,就递归向上,总之先找到第一个候选点 A。

第二步:以 z 为圆心,z 到 A 的距离为半径,做一个球体 S,把球体 S 同八叉树求交(离 z 最近的点一定落在这个球体范围内),筛选出有交集的叶子节点包围盒,然后迭代这些叶子节点包围盒里的点,一旦找到更近的就缩小球的范围,这样就能找到离 z 最近的点了。

如果要找前 k 个距离最近的点,你需要维护一个长度为 K 的优先队列(或者最大堆),在找到最近邻居的基础上,将兄弟节点邻近的候选点都填充到队列里,直到队列里装满 k 个点,此时以 z 为圆心,队列里第 k 个离 z 最近的点为半径,对八叉树做一次范围搜索(前 k 个点一定落在该范围内),搜索过程中不断更新优先队列并及时根据最新的第 k 个点离 z 的距离调整半径。

Loading

Posted in 图形编程 | Tagged | Leave a comment

我在命令行下剪辑视频

是的,你不需要格式工厂,你也不需要会声会影,更不需要爱剪辑这些莫名其妙的流氓软件,命令行下视频处理,包括剪辑,转码,提取,合成,缩放,字幕,特效等等,全部命令行搞定,这不是疯狂,而是效率:

MP4 转换 GIF

知乎可以发 MP4,但对桌面录屏这种十多二十秒的小短片远远没有 GIF 来的便捷,GIF 在很多软件里支持的也比 MP4 要广泛,转换命令为:

ffmpeg -i in.mp4 -an -c:v gif out.gif

参数 -i 的指明输入文件 “in.mp4” ,-an 代表禁用音频,-c:v 的意思是指定视频编码为 gif,最后是输出文件名。

那么效率在哪里呢? 别急,我们写完善点,做个脚本:video_convert_to_gif.cmd

@echo off
if "%1" == "" goto HELP

set "IN=%1"
set "OUT=%~dpn1.gif"

if "%2" == "" goto NEXT
set "OUT=%2"
:NEXT

call ffmpeg -i "%IN%" -an -c:v gif "%OUT%"
pause
goto END

:HELP
echo usage: video_convert_to_gif ^<input^> [^<output^>]
:END
echo.

将上面的脚本完善一下,保存成名为 video_convert_to_gif.cmd 的脚本:

每次要使用的时候,直接把任何格式的视频文件拖到这个脚本上面去,同级目录下就有了一个 gif 文件了,比你格式工厂修改一半天点点点来的高效多了。

转换为 MP4

最简单写法:

ffmpeg -i in.wmv -c:v libx264 -c:a aac out.mp4

前面输入可以是任意格式的视频文件,用 -c:v 指定视频编码器是 libx264,用 c:a 指定音频编码器是 aac,然后输出 mp4,考虑到某些安卓机可能无法正确播放,完善下:

(点击 more/continue 继续)

Continue reading

Loading

Posted in 随笔 | Tagged | Leave a comment

学习 Vim 的三个阶段

学习使用 vim 有三个阶段:

首先是孩童时期,刚刚开始接触 Vim,觉得非常别扭,这里也不顺畅,那里也不够高效,表现为在知乎上问,“Vim 到底好在哪里?”,或者“学完 vimtutor 以后该干嘛?”

接下来是青春期,感受到 Vim 的爽点,开始欣喜若狂的探索 Vim 的边界,表现为疯狂的尝试各种 mapping 和插件,阅读网上一切关于 Vim 的文章和内容,尝试一切可能的事情。

最后进入成熟期,开始移除所有无用的东西,真正变得高效起来。表现为开始冷静思考自己的工作流程,逐步针对性定制 vim ,让 vim 越来越顺手。

只有对编辑器足够挑剔的人,才会使用 Vim。真要尝试,你要先问问自己是不是对编辑器有很高的要求,是不是对身边的编辑器都有不满意的地方,还是只是好奇,并不希望投入多少时间:

当你真的决定入坑了,那么主要问题就是怎么完成第一个阶段到第二个阶段的切换呢。

(点击 more/continue 继续)

Continue reading

Loading

Posted in 随笔 | Tagged | Leave a comment