记一次 Python GUI 框架的选择

为什么要使用 Python 写 GUI 程序?

这得说到我最近在维护的开源项目 InputShare 了。

这个项目最开始是没有图形界面的,我想着使用 Python 的话一方面能够快速验证,另一方面 Python 的社区资源足够丰富,就选择使用 Python 编写原型。

在软件基本可用后,我想着给它加上一个易用的图形界面方便我自己使用,也能让软件方便推广。此时我依然延续了原型设计的思维,选择了我还算熟悉并且能够快速做出界面的 tkinter 和 CustomTkinter

但是在最近,我想要改动设置界面,将设置项进行分组,并添加新的设置项,我发现相关的 UI 代码很难修改。

同时,我尝试使用英文版本界面录制推广视频时,意外发现 CustomTkinter 没有自带文本溢出换行!我需要手动在文本中添加 \n 来实现换行!

于是我开始尝试使用其它的 Python GUI 框架进行重构。

我调研了哪些替代品?

大概内容可以参考这个 issue

我先后调研了如下 GUI 框架:

Flet

看起来很好,是 Flutter 的 Python 封装,跨平台性很好,并且自带多平台构建支持。

经过基本了解后我发现 Flet 并不很适用于 InputShare 这种主要运行在后台的应用,使用这个框架可能需要大幅重构项目,遂放弃。

PyQt + QFluentWidgets

基于成熟的 PyQt,并且使用的 fluent design 也足够美观。

但是我在尝试的过程中发现其文档并不好懂,很多好用一些的组件需要付费,并且官方的 Gallery 实例的性能并不好,目测只有 30 帧。

pywebview

封装了原生的 Webview 并提供 Python Binding,可以使用 Web 前端代码开发界面,也提供了 Python 和 JavaScript 的通信支持,看起来很美好。

但是这个库控制的窗口没有黑暗模式的支持,即使当系统处于黑暗模式时,窗口的边框依然处于日间模式

我尝试过将窗口设为无边框,库倒是有将 DOM 元素设为窗口可拖拽区域的支持,但是在无边框模式下窗口无法被鼠标调整大小

遂放弃。

webui

这个项目另辟蹊径,使用系统安装的浏览器作为应用窗口,并提供包含 Python 在内的多语言支持。

但是在我把示例代码跑起来后就发现了问题,如这个 issue 中所示。遂放弃。

PyQt + QtWebEngine(尝试中)

我在放弃 webui 后想到,要展示前端界面,我未必非得用专门的框架。像 PyQt 这样框架就已经有成熟的 Webview 支持了。

我在成功把内嵌 Webview 的 Qt 窗口运行之后,尝试封装一个专门的库用于展示前端界面。为了这盘醋包了顿饺子了属于是

这个经历给了我两个教训

  1. Python 真的不适合用于图形界面程序开发。

  2. 引自《程序员修炼之道》,不要把原型用于产品。

文章最后,是《程序员修炼之道》的原文引用:

不要把原型用于产品

在开始任何基于代码的原型开发之前,请确保每个人都理解,正在编写的是一次性代码。原型可能有着欺骗性的外表,对那些不知道这只是原型的人产生吸引力。你必须非常清楚地表明该代码是用完即弃的,它并不完整也不可能做到完整。

如果你觉得所在的环境或文化中,原型代码的目的很有可能被误解,那么最好使用曳光弹的方法。这样,最后你可以做出一个坚实的框架,在此基础上进行未来的开发。


本文转自我的个人博客,点此查看原文

乱说。Python 的 PyQt 和 PySide 很多人拿来写生产型项目。我之前也使用 PyQt 搞过两三万行代码的项目。知乎有个韦易笑,弄了个 PyStand 还能很方便地打包应用,或者用 Nuita 也能把 PyQt 项目编译成 exe. 不过 PyQt 是 GPL 软件,如果想用 LGPL 搞闭源项目应该用 PySide.

Python 搞 GUI 开发正统的就 PyQt/PySide,那种 Tkinter 是初学者行为。再选其它库都是玩票性质。

正常的创业都是弄个原型出来投放市场快速验证商业循环。而不是做得尽善尽美再去投放的。所以 Python 可以说最佳的软件创业编程语言。

PySide + Django + VUE,几乎可以应付 99% 的软件项目。需要 Android 就 Web 套个壳也能搞出来。

2 个赞

以前也看了不少,最后还是选择 tkinter,日常写写小工具用用足够,自带也不用折腾环境

劝你们别再继续用这个 Tkinter,它的思维与一般的 GUI 框架很不一样。API 是 90s 的思维方式,相当的不 Pythonic. 用得多了会影响你们使用 Python 方式。

而且 Tkinter 的控件特别少,初期写可以还行。稍微大一点的程序需要接入第三方模块啥的,你会发现用不了。到时就是改不行,不改也不行。

本人是 20 年的 Python 老鸟看过不少这样的事例。

PyQt/PySide 文档多,思路清晰。代码示例多,github 上面的第三方模块也多。因为代码基大,所以使用 AI 生成代码也非常方便。要用 Python 写 PC GUI,推荐用这个。

本来想推荐 PySimpleGUI 的,结果刚去看了一下,开发团队吃不消了,7年的项目结束了 :crying_cat:

都说了是小工具了 :joy: 用的时候把API都封装了基本就是对象化操作了,就是大量定义堆在一起可能看着有点难受

你的用不了是指什么?

这也是我经常担忧的,第三方库最后死掉了。当然这是最坏的情况,更多的是版本更新API变更得重新修正。

tkinter 封装的功能非常少。只有最简单的控件。知乎上面很多人谈到这事。我发两条链接给你看看。

为什么很多Python开发者写GUI不用Tkinter,而要选择PyQt和wxPython或其他? - 强强同学的回答 - 知乎
https://www.zhihu.com/question/32703639/answer/170291468

为什么很多Python开发者写GUI不用Tkinter,而要选择PyQt和wxPython或其他? - 韦易笑的回答 - 知乎
https://www.zhihu.com/question/32703639/answer/2311119286

其中这个韦易笑有个 PyStand 是专门给中国的 PyQt 软件开发者使用的。这人算是知乎知名的软件开发方面的大 V 了。

1 个赞

大致看了下。

第一个回答里面很多应该是没有读文档导致的,当然大部分人估计也不会去去那么长的文档。然后用的人比较少,社区教程资源不丰富,导致很多人用不上手。

比如 “本想实现输入框中内容被改变时,该内容文字颜色变为红色的功能,但是找了半天,没有,或者是藏得很深,让人误以为没有”,这样的功能是可以通过 tkinter 参数 validatecommand 实现的。

代码的布局是繁琐了点,但习惯了也还好。大项目挤成一堆可能不太好维护。

第二个回答里也有和第一个回答里类似的部分。里面还提及文档奇缺,这确实是一个重要的因素,当初我刚用 tkinter 的时候确实头痛好久,但现在基本熟悉了。

第三方 GUI 框架确实也提供了丰富的接口,便于快速开发。但 tkinter 也不是不能做到,只是繁琐了点。暂时还没有看到 tkinter 完全不能实现的需求。

所以我觉得一般用用是没问题的。

Snipaste_2025-03-25_00-02-00.png

其中一个用 tkinter 写的,确实一长串(

tkinter 的文档本来就少。我当年也是读过的。离 Qt 是差十万八千里。关键是 tkinter 的 API 设计得很差,就是我所说的不 pythonic. 而 Qt 经常可以做到,只要看函数签名就知道函数怎么调用。

那个 PyStand 我也看到了。这个帖子没有说 pyqt 不好,其实吐槽性质更多一些。
不过我目前好像没见过什么成熟的图形界面是用 pyqt 或者 pyside 写的,倒是这几年新出的 tauri 已经看到好多实际的用例了。
我在想,其实应该先用Python写个命令行程序跑通原型,然后直接用 rust + tauri 写的。

如果是快速搭建项目的话,我比较倾向于python+fastAPI+vue(react)

用 rust 是另一回事。

不过你再试试就会知道,rust 一般拿来做系统开发,比如开发个操作系统、数据库啥的。rust 追求内存安全和高效,必然会损失掉开发效率。

写界面这种活,python 和 js 是最合适的。其它语言做起来都很繁琐。

对。能用 web 就 web 吧。现在谁做 PC 软件。

tauri 也是基于 webview 的,只是一些原生的功能需要在 rust 层实现,然后再给 web 层提供 binding