太强了!Python 开发桌面小工具,让代码替我们干重复的工作-

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了太强了!Python 开发桌面小工具,让代码替我们干重复的工作-相关的知识,希望对你有一定的参考价值。

参考技术A 决定写这篇文章的初衷是来源于一位小伙伴的问题,关于"如何根据数据源用 Python 自动生成透视表",这个问题背后有个非常好的解决思路,让代码替我们做重复的工作,从而减轻工作量,减少出错。

Python 开发的小工具实际上是将 Python 程序打包成 exe,分享即可用,即便电脑没有安装 Python 环境,也可以使用,用代码提高工作效率,尽量少加班。

将工作中重复性的操作,利用供应商名称,月份,入库金额三个字段来生成想要的透视表格式。

创建桌面窗口,这里使用 tkinter,它是 Python 自带的 GUI 库,安装后即可使用。

使用 pyinsatller 将程序打包成 exe,好处是不需要将代码部署到服务器,直接将打包好的 exe 发给对方,就能直接使用,对于这种小而轻的功能非常友好。

Excel 文件生成透视表和筛选数据,文件名:excel_to_pivot.py

设计桌面窗口功能,文件名:opration.py

如果运行结果如上,说明代码没有问题了,可以进行下一步。

打开 DOS 窗口并切换到 两个 py 文件所在的目录,注意路径中不要有中文。

pyinstaller 指令的常见可选参数:

在当前的目录下,将会生成两个文件夹:build 和 dist。dist 里面就是所有可执行 exe 文件,发送快捷方式到桌面,点击 opration.exe 就能运行了,可以发它的快捷方式发送到桌面,双击就可以。

有的伙伴 Python 环境刚安装没多久,可能不存在这个文件过大的问题。像我的电脑里安装了 Python 很多的依赖包和 anaconda 等等,打包出来的文件居然 660M,打包时间长,执行时还卡,后来经过整改缩小到 31M,打包快,秒级执行。解决方案是在 Windows 系统下安装一个 Python 的虚拟环境,前提是已经在电脑上安装过 Python 才可以进行如下操作。

找到 Python 所在路径,如果忘记了,可以在电脑左下角搜索【编辑系统环境变量】——【用户变量】——【PATH】中找到

虚拟环境可以理解为是 Python 解释器的一个副本,在这个环境你可以安装私有包,而且不会影响系统中安装的全局 Python 解释器。虚拟环境非常有用,可以在系统的 Python 解释器中避免包的混乱和版本的冲突。

重要是不同虚拟环境可以搭建不同的 Python 版本,创建时候选择,我们这里需要一个相对 "干净" 的 Python 环境,没有安装过多依赖包,避免 exe 打包文件过大,所以用到虚拟环境。

进入虚拟环境,可以看到只有几个默认的 Python 库

这时可以测试一下代码,是否缺少相关依赖,比如我这个缺少 Pandas,openpyxl,依次按照 pip install 包名安装即可,非常重要的点:pyinstaller 必须重新安装,文件才会缩小。

上述操作完成后,打包就可以了,最后退出虚拟环境即可。

退出虚拟环境

整个自动化思路的实现就完成了,大家可以将整个流程套用到你现有的重复性工作中,在过程中有两个需要注意的点,如下:

尽量不要用中文路径,要不会报些莫名其妙的错误。

导包是尽量避免使用 import * 导入不必要的包,节省打包和执行时间。

让代码自动工作,省下来的时间,摸摸鱼,打打小 游戏 不好么~

TaskHosting - 开发桌面工具原来还可以这么简单

由来

对于喜欢开发的我经常会写一些小工具,这些小工具多以功能为主,不要求漂亮、个性化的UI。但起码要保证使用方便,因此最基本的功能要有:

  • GUI(图片用户界面)
  • 程序配置的保存与读取(让用户在GUI上操作要方便)
  • 用户使用习惯的自动记录(例如:上次关闭时窗口位置及大小等)
  • 程序崩溃捕获及上报
  • 实时显示运行日志(当前执行到哪步了,输出结果是什么)
  • 多线程管理及调度框架

如果每个工具都要COPY一遍以上功能的代码以后维护起来是个大坑,封装成库调用呢?那每个工具都要写一遍组装UI组件的代码。

仔细想一下,其实我要写的就是一款小工具,它以实现功能为主。

那么我就需要有一个开发框架,它可以让我只专注于功能(业务)的实现,简化UI相关的编码,最好是能用一行代码就实现一个UI功能,这个开发框架现在写好了我给它取名为TaskHosting 

 

TaskHosting初识

先来张截图看看它长什么样~_~

TaskHosting界面中大部分UI都是可以自定义的,大部分情况下只需要2-3行C#代码就可以定制一部分UI功能,如果你不会WPF也可以用WinForms定制里面的UI(通过WindowsFormsHost)

当然我们的目标是不关心UI,专注于功能实现,让我们来看下如何使用它。

首先从Hello Word开始:

  1. 首先要创建一个类库项目,然后引用TaskHosting框架相关类库
  2. 项目属性 > 调试 > 启动操作 > 选择【启动外部程序】,路径填写TaskHosting.exe的路径
  3. 创建一个【任务】类 HelloWordTask.cs,代码如下(现在先不用明白什么意思,后面会有介绍)
     1 [Task("Hello Word", IsMutilThread = true, ConfigType = typeof(Config))]
     2     class HelloWordTask : Mondol.TaskHosting.Task
     3     {
     4         private readonly Config _cfg;
     5         private readonly IImmediateLogger _immediateLogger;
     6 
     7         public HelloWordTask(Config cfg, IImmediateLogger immediateLogger)
     8         {
     9             _cfg = cfg;
    10             _immediateLogger = immediateLogger;
    11         }
    12 
    13         public override void OnRun()
    14         {
    15             _immediateLogger.Info($"设置1的值为: { _cfg.Setting1}");
    16             _immediateLogger.Info($"设置2的值为: { _cfg.Setting2}");
    17         }
    18     }
    19 }
    View Code
  4. 创建一个【任务】的配置类 Config.cs,代码如下:
     1 class Config : Mondol.Configuration, ITaskConfig
     2     {
     3         private readonly IAppEnvironment _appEnv;
     4 
     5         public Config(IAppEnvironment appEnv)
     6         {
     7             this._appEnv = appEnv;
     8         }
     9 
    10         protected override string GetConfigurationFilePath()
    11         {
    12             return Path.Combine(_appEnv.GetPluginDataBasePath(GetType().Assembly), "HelloWord.Config.json");
    13         }
    14 
    15         [Category("基本设置"), DisplayName("设置1"), Description("程序设置1,存储 string 类型的设置")]
    16         public string Setting1
    17         {
    18             get
    19             {
    20                 return GetProperty(nameof(Setting1), "我是设置1的默认值");
    21             }
    22             set
    23             {
    24                 SetProperty(nameof(Setting1), value);
    25             }
    26         }
    27 
    28         [Category("基本设置"), DisplayName("设置2"), Description("程序设置2,存储 int 类型的设置")]
    29         public int Setting2
    30         {
    31             get
    32             {
    33                 return GetProperty(nameof(Setting2), 5);
    34             }
    35             set
    36             {
    37                 SetProperty(nameof(Setting2), value);
    38             }
    39         }
    40     }
    View Code

运行程序,效果如下:

怎么样,是不是很简单?

 

有什么功能

目前TaskHosting有如下功能:

  • 强大的日志功能
    • 输出到UI中的即时日志也可以存到文件、数据库、甚至远程服务器
    • 程序崩溃自动将异常记录日志
    • 即时日志可按日志级别(跟踪、调试、信息、警告、错误、致命)过滤显示
    • 可用专用的文件日志分析工具
  • 方便的配置存取
    • 每个【任务】都可以有自己的配置文件
    • 配置文件自动读取、自动保存
    • 配置项可限制数据类型、支持拖拽
    • 配置项可加详细描述
  • 自动记录使用习惯
    • 重新打开软件会恢复上次选择的【任务】、窗口大小、位置等
  • 崩溃捕获及上报
    • 自动捕获未处理异常,并显示友好错误处理窗口
    • 未处理异常可自动上报服务器、发邮件或由用户处理
  • 多线程调度框架
    • 经过优化的线程调度框架、最大化利用系统资源
    • 【任务】可决定是否启用多线程
  • 更多特性还在完善中。。。

以上功能均可灵活的自定义,TaskHosting的目标 - 简洁而不简单

 

设计概念

TaskHosting是一个【任务】的管理器(继承自Mondol.TaskHosting.Task的类就是一个任务),每一个【任务】对应一个功能,例如:网址采集任务、数据同步任务等。

【任务】的类来自于你编写的类库项目(下称插件),每一个插件可以包含多个任务。

 

参考上面的HelloWordTask类,它继承了Mondol.TaskHosting.Task所以它是一个任务,将来会显示在【任务:】列表中。

你可以用Task属性来指定任务的名称、是否支持多线程、配置类类型等

 

无处不在的依赖注入

依赖注入是一个很简单的概念,例如:ClassA依赖于ClassB,ClassB又依赖于ClassC,传统的硬编码方式是先分别new出ClassB、ClassC才能new ClassA。

依赖注入框架会管理这种依赖关系,使用时无需关心谁依赖谁,只需要告诉框架我需要ClassA的实例,它就会自动帮你创建出来。

详细依赖注入的概述网上有很多介绍文章,大家找一下就好了。

TaskHosting采用了Autofac来管理模块间的依赖关系,TaskHosting支持3种类型注册的方式:

  • 编码注册
        //相当于程序的Main方法所属类(后面会详细介绍)
        internal class Initializer : IInitializer
        {
            public void ConfigureServices(ContainerBuilder builder)
            {
                //Autofac的方式注册
                builder.RegisterType<Config>().AsSelf();
            }
        }
  • 属性注册
        //通过属性注入,可指定是否单例、作用域
        [Injection(AsType = typeof(Config), IsSingleInstance = true, Scope= InjectionScope.Running)]
        class Config
        {
            //类实现...
        }
  • 自动注册
    所有实现了ITaskConfig接口的类都会自动注册为单例,例如:
    class Config : Mondol.Configuration, ITaskConfig
        {
            //类实现...
        }

除了插件自己注册的类型外,框架还会注册一些接口给插件使用,例如:

  • IAppEnvironment  //APP环境
  • IEventManager  //事件管理器
  • IImmediateLogger //即时日志输出接口

更多接口请参见Mondol.TaskHosting.Abstractions.dll程序集,这个程序集里全是接口定义,里面的接口将来都可以通过依赖注入获取到

 

小结

以上简单的介绍了TaskHosting的概念及基本用法,其目的就是让你可以更专注于功能业务的开发,而无需过多关心UI实现细节。

后续会详细介绍一些高级的使用方法及示例

 

使用中如有什么意见或问题欢迎随时反馈给我Q46029811

以上提到的示例代码:单击下载

以上是关于太强了!Python 开发桌面小工具,让代码替我们干重复的工作-的主要内容,如果未能解决你的问题,请参考以下文章

太强了,Python 开发桌面小工具,让代码替我们干重复的工作

基于pywebview的桌面小工具开发记录

Android桌面小部件AppWidget开发

Python爬虫实战,破解有道翻译JS加密,制作桌面翻译工具更新版

让你的代码减少90%,这些Java工具库太强大了!

开发Python用啥工具好