纯 HTML 与纯 Python 小工具的一个尝试(附遇到的坑与解决办法) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
cmdOptionKana
3.16D
V2EX    分享创造

纯 HTML 与纯 Python 小工具的一个尝试(附遇到的坑与解决办法)

  •  
  •   cmdOptionKana 2020 年 3 月 9 日 4563 次点击
    这是一个创建于 2182 天前的主题,其中的信息可能已经有所发展或是发生改变。

    会编程的人,总会想做些小工具。

    通常,小工具如果有 GUI 界面会比较直观。

    但是,用什么来做 GUI 是个问题,如果用 C#, 会局限于 win 系统,如果用 Java 则需要拖着一个 jvm, 如果用 Electron 又体积巨大占用内存多……

    后来发现了 TiddlyWiki, 它的实现方式很另类,就单独一个 html 文件,我感觉这对于不太复杂的小工具来说, 是个极好的方式!因为:

    • 免安装
    • 天生跨平台
    • 网页做 GUI 界面非常方便,生态好,有大量优秀的 UI 库
    • 近年来前端技术发展非常良好,对于一个小工具来说,网页本身就能实现大部分需求, 最大的缺点就是无法直接保存数据到本地而已。

    作为一个尝试,最近做了一个小工具 ( https://github.com/ahui2016/small-plans 上周发布, 最近几天有几个重要改进 ), 采用类似 TiddlyWiki 的方式.

    TiddlyWiki 把用户数据也保存到 html 文件里, 结果导致升级 TiddlyWiki 本身非常麻烦

    • 当 TiddlyWiki 本身有变化时,它需要一个复杂的方式小心翼翼地把用户数据剥离出来,升级自身后, 再把用户数据填充回去。
    • 我的解决方案是,以 json 形式导出用户数据。TiddlyWiki 点击保存按钮是下载一个包含自身程序与 用户数据的 html 文件,我的方案则是点击按钮下载一个用户数据 json 文件。
    • 我的方案的缺点是,TiddlyWiki 不需要导入数据,我的则需要。但由于平时用户数据会保存在浏览器里, 因此不需要频繁导入数据,这个缺点不算太严重。
    • 优点是升级方便,程序本身(即一个 html 文件)完全可以随时被覆盖,升级就是用新版直接覆盖旧版, 用户数据完全不受影响!
    • 由于数据与程序分离,后续可以非常方便地通过 api 与各种云盘、云储存或自建服务器收发数据。

    浏览器没有权限获取本地文件夹地址

    • 据我所知 TiddlyWiki 明显有一个麻烦的地方:点击保存,直接下载文件,但无法让程序帮忙自动选择目录, 每次都需要手动移动文件。
    • 我想到的解决办法是,获取当前网址。由于是本地文件,因此网址就是本地目录地址。
    • 然后我提供一个复制按钮给用户,然后在选择文件的窗口里粘贴按回车,即可快速定位到当前目录。

    主要功能在 html 里做,但有时可能需要做一些周边的辅助工具

    • 根据具体情况而定,有时一个 html 就足够了,有时增加一个或几个额外的工具会更方便
    • 比如我需要这样一个功能:
      • 让用户选中几个本地文件(旧版本)
      • 自动从 GitHub 仓库里下载一个文件(最新版本)
      • 把多个本地文件的内容替换为最新版本
    • 显然,无法让 html 文件来完成,最后我找到一个 Python 的 GUI 库

    强烈推荐 appJar!

    • 易用,非常易用,即学即用,极易上手(我考虑要不要帮他写个中文版的教程)
    • 它的底层是 tkinter, 因此只要有 Python 环境就能运行,没有第三方依赖,不需要 pip install
    • 缺点是界面超丑,但不拿来做主程序,只拿来做周边的辅助工具,考虑到它易学易用、无依赖、跨平台、 快速产出等优点,丑一点也可以接受吧。

    结论

    • 鉴于前端技术的发展,现在做小工具,完全可以考虑这种方案:单个 HTML 文件
    • 如果需要额外的辅助工具,推荐这个超级易学易用的 GUI 库: appJar
    第 1 条附言    2020 年 3 月 10 日
    21 条回复    2020-03-25 20:31:28 +08:00
    loginv2
        1
    loginv2  
       2020 年 3 月 9 日
    都用 python 了,本地起一个 HTTP 服务做 UI,用浏览器访问不就行了么
    tomxin7
        2
    tomxin7  
       2020 年 3 月 9 日
    这不是还需要 Python 的环境才能运行吗
    cmdOptionKana
        3
    cmdOptionKana  
    OP
       2020 年 3 月 9 日 via iPad
    @loginv2 不需要 python,不需要服务器,就一个 html 文件,别的啥都不用,类似于 TiddlyWiki
    @tomxin7 不需要 python
    fx0719
        4
    fx0719  
       2020 年 3 月 9 日 via iPhone
    标记一下,偶尔做个小工具说不定用的上
    ps1aniuge
        5
    ps1aniuge  
       2020 年 3 月 9 日
    mokain
        6
    mokain  
       2020 年 3 月 9 日
    用 nodejs 写 web 服务难道不香吗?都是 html 呈现,数据还能本地保存与上传 github,只需一个 nodejs !
    cmdOptionKana
        7
    cmdOptionKana  
    OP
       2020 年 3 月 10 日
    @ps1aniuge 我才发现这种方式被墙了……我想想怎么改下载说明
    cmdOptionKana
        8
    cmdOptionKana  
    OP
       2020 年 3 月 10 日
    @mokain nodejs 也很香,事实上我这个工具第一版就是用 Golang 做后端,用 Vue 做前端。

    后来改成现在这种方式。从这个工具的使用情境来看,现在这种方式比 web 服务器好太多了。

    现在可以跟着项目走,跟着项目一起 git push,使用时也不需要先启动本地服务器,各方面的心理负担都小了很多。

    举个例子,多个项目同时使用这个程序时,如果用你说的 web 服务器的方式,“上传到 github” 这个部分怎样处理?(是集中上传到一个仓库,还是分别上传到各自的仓库,如果分开仓库,要怎样设置)

    程序的启动方式怎样处理?(要在控制台输入命令吗,需要先切换文件夹吗,根据启动时的文件夹只显示当前项目的内容,还是不用切换文件夹启动后显示一个项目列表?)

    总之,最后我发现现在这种方式有它的优点,一个 html 文件就是一个独立的程序,很多问题都得到了简化。
    dyxang
        9
    dyxang  
       2020 年 3 月 10 日 via Android
    项目看起来挺完整的,收藏先,就是没有常见的 demo……然后就是项目的分类是 python
    ps1aniuge
        10
    ps1aniuge  
       2020 年 3 月 10 日
    @dyxang 对头,有请楼主弄张 gif 图例。
    cmdOptionKana
        11
    cmdOptionKana  
    OP
       2020 年 3 月 10 日
    cmdOptionKana
        12
    cmdOptionKana  
    OP
       2020 年 3 月 10 日
    @dyxang
    @ps1aniuge 谢谢建议!我去 coding 搞了个 demo 页面, 请看附言。
    viperasi
        13
    viperasi  
       2020 年 3 月 10 日
    tiddlywiki 用了好多年,之前也研究过 tiddlywiki 的方式。
    好东西,star 了
    viperasi
        14
    viperasi  
       2020 年 3 月 10 日
    还有个问题, tiddly wiki 还有一个自动版本的功能,每次保存都会生成一个新后缀名的文件,这部分 LZ 是通过 github 来实现,而不作为自身的功能吗?
    cmdOptionKana
        15
    cmdOptionKana  
    OP
       2020 年 3 月 10 日
    @viperasi 对,这个不打算作为自身功能了,这个工具主要使用场景是连同项目其它文件一起 git push 的。

    以后做别的工具我再考虑版本问题,而且,如果不是这种使用 git 的场景,我还打算把上传到云端的功能也做进去。
    viperasi
        16
    viperasi  
       2020 年 3 月 13 日
    能否添加分组,或者按照添加时间在 todo 之上添加一个时间的标题?
    ![图片]( )
    cmdOptionKana
        17
    cmdOptionKana  
    OP
       2020 年 3 月 13 日
    @viperasi 我想了一下,这个用原生 Javascript 写有点麻烦,暂时想让这个项目尽量简单一些。

    但你的建议非常好,有日期标题是感觉不错,以后我会重写这个项目,到时会加上这个。
    viperasi
        18
    viperasi  
       2020 年 3 月 13 日
    @cmdOptionKana github 上发了 pr, 顺便吐槽一下那个.idea, clone 了好久
    cmdOptionKana
        19
    cmdOptionKana  
    OP
       2020 年 3 月 13 日
    @viperasi 谢谢支持!已 merge !
    midpoint
        20
    midpoint  
       2020 年 3 月 25 日
    appJar 简单好用
    cmdOptionKana
        21
    cmdOptionKana  
    OP
       2020 年 3 月 25 日
    @midpoint 功能稍复杂一点的话还是不如 web 做界面舒服,但用来做辅助工具是极好的~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1033 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 18:47 PVG 02:47 LAX 10:47 JFK 13:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86