当前位置: 首页 > news >正文

tkinter-TinUI-xml实战(12)pip可视化管理器

引言

pip命令行工具在平常使用方面确实足够简单,本项目只是作为TinUI多界面开发的示例。

当然,总有人想用GUI版pip,实际上也有。不过现在,我们就来手搓一个基于python和TinUI(tkinter)的pip可视化管理器。

命名为“pip集合功能平台”:Pip Integration Platform(PIP)

没错,我就是故意的。

项目开源地址:Github · Pip Integration Platform。

文件结构

│  gui.py 界面控制
│  main.py 主程序
│  pipmode.py pip功能控制
│  TinUI.py UI支持
│
├─lib
│  ├─gui 三个界面
│  │  │  gui_install.py
│  │  │  gui_list.py
│  │  │  gui_uninstall.py
│  │
│  └─operate pip功能的具体实现
│      │  pip_install.py
│      │  pip_list.py
│      │  pip_uninstall.py
│
├─pages 页面设计
│      main.xml
│      p1_libs.xml
│      p2_install.xml
│      p4_uninstall.xml

结构说明见PIP程序结构。

页面设计

无论最终结果是什么样,先把能够看的搭建起来。本项目的四个界面均使用TinUI库自带的TinUIXml编辑器。

main.xml为简单的标签页控件,这里不展示。

p1_libs.xml

<!--TinUIXml编辑器-->
<tinui><line><listbox width='760' height='460' data='("TinUI",)' command='self.funcs["sel_libs"]'>lsbox</listbox></line><line><button2 text='打开文件位置' command='self.funcs["opendoc"]'></button2><button2 text='打开项目页面' command='self.funcs["pypidoc"]'></button2><button2 text='卸载' command='self.funcs["uninstall"]'></button2><button text='检测全部可更新项目' command='self.funcs["update"]'></button></line>
</tinui>

在这里插入图片描述
p2_install.xml

<!--TinUIXml编辑器-->
<tinui><line y='20' anchor='w'><paragraph text='第三方库名:'></paragraph><entry width='300'>entry</entry><checkbutton text='升级' command='self.funcs["update_switch"]'>check</checkbutton><button2 text='开始安装' command='self.funcs["install"]'>button</button2></line><line><textbox width='760' height='480' scrollbar='True'>textbox</textbox></line>
</tinui>

在这里插入图片描述

p4_uninstall.xml

<!--TinUIXml编辑器-->
<tinui><line y='20' anchor='w'><paragraph text='要卸载的库:'></paragraph><entry width='300'>entry</entry><button2 text='开始卸载' command='self.funcs["uninstall2"]'>button</button2></line><line><textbox width='760' height='480' scrollbar='True'>textbox</textbox></line>
</tinui>

在这里插入图片描述

界面交互

PIP的总界面管理见gui.py。

各项功能界面见PIP的lib.gui.*。

子线程运行pip命令

因为pip命令大多为耗时命令,因此在PIP中,pip命令将被放置在子线程中运行,在运行结束后会调用回调函数并触发窗口事件,结束子线程并在界面线程中展示操作结果。

这种做法不仅不会阻碍界面线程,还能够在界面线程实时显示命令行输出信息。以安装(install)功能为例。

gui_install.py

#...update=False#是否升级,用于调整pip参数
update_page=False#升级检测页面是否打开
update_page_id=None#升级检测页面对应到TinUI.notebook的页面id
book=None#标签页控件
ui=None#标签页中对应的BasicTinUI#...
def install():#开始下载(执行pip命令,不判断正误)name=entry.get()entry.disable()check.disable()button.disable()pipmode.install(update,name,add_msg,end)def add_msg(_msg:str):#接受pip_install的信息global msgmsg=_msgtextbox.event_generate('<<NewMsg>>')
def _add_msg(e):#接受pip_install调用add_msg传递的信息textbox.config(state='normal')textbox.insert('end',msg)textbox.see('end')textbox.config(state='disabled')def end():#接受pip_install停止操作textbox.event_generate('<<End>>')
def _end(e):#操作结束,按钮恢复entry.normal()check.active()button.active()textbox.config(state='normal')textbox.insert('end','====================\n\n')textbox.config(state='disabled')#...

pip_install.py

"""
/lib/operate/pip_install.py
升级和安装的第三方库
"""
import subprocess
import threadingdef __install(update,name,msgfunc,endfunc):if update:#已安装,升级cmd="pip install --upgrade "+nameelse:#安装cmd="pip install "+namemsgfunc(cmd+'\n')result=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True)for line in iter(result.stdout.readline, b''):msgfunc(line.decode('utf-8'))endfunc()def install(update,name,msgfunc,endfunc):thread = threading.Thread(target=__install,args=(update,name,msgfunc,endfunc,))thread.setDaemon(True)thread.start()

可以看到,界面按钮通过pipmode.py调用了lib.operate.pip_installinstall方法,创建了一个名为thread的线程并在其中运行pip命令。

我们注意__install方法中,存在msgfunc(...)endfunc(...)的回调,再看看gui_install.py中对应的add_msg(...)end(..)方法。我们着重看add_msg方法,其中只进行了两步,第一步是将返回值变为全局变量,本进程公用;第二步触发界面的虚拟事件<<NewMsg>>,后续步骤脱离子线程,而子线程一直运行,直到回调endfunc(...)

这个时候,因为虚拟事件被触发,gui_install.py在主线程开始运行_add_msg方法,实现对信息流的GUI展示。

各项pip功能见PIP的lib.operate.*。

子线程回调见PIP的多线程回调方式。

效果

初始化

在这里插入图片描述

安装

在这里插入图片描述

更新

检测更新是一个漫长的过程。

在这里插入图片描述

返回库列表点击按钮只是为了展示界面线程运行正常。

在这里插入图片描述

卸载

在这里插入图片描述

结语

这就是我们手搓的一个简易pip功能集合平台。

详细内容见开源项目地址:Github · Pip Integration Platform。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 新书速览|Vue.js 3.x+Express全栈开发:从0到1打造商城项目
  • 数据结构与算法(1):递归函数的设计技巧
  • PostgreSQl 物化视图
  • 秒懂设计模式--学习笔记(9)【结构型-装饰器模式】
  • nginx正向代理、反向代理、负载均衡
  • 【C++】构造函数详解
  • 机器人及其相关工科专业课程体系
  • 批量提取PDF指定区域内容到 Excel , 根据PDF文件第一行文字来自动重命名v1.3-附思路和代码实现
  • qt 返回上级页面
  • Java如何使用 HttpClientUtils 发起 HTTP 请求
  • C++(week11): C++基础 第六章:关联式容器 set、map
  • 2 Java的基本程序设计结构(基本语法1)
  • 外包干了1个月,技术明显退步。。。
  • SparkStreaming--scala
  • Apache访问机制配置
  • 时间复杂度分析经典问题——最大子序列和
  • 《Java编程思想》读书笔记-对象导论
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • eclipse(luna)创建web工程
  • If…else
  • Java Agent 学习笔记
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • SpiderData 2019年2月16日 DApp数据排行榜
  • spring学习第二天
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 实现简单的正则表达式引擎
  • 试着探索高并发下的系统架构面貌
  • 移动端 h5开发相关内容总结(三)
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • Java总结 - String - 这篇请使劲喷我
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​2020 年大前端技术趋势解读
  • # 安徽锐锋科技IDMS系统简介
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (7)摄像机和云台
  • (BFS)hdoj2377-Bus Pass
  • (C语言)共用体union的用法举例
  • (PADS学习)第二章:原理图绘制 第一部分
  • (vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
  • (八)Flink Join 连接
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二)JAVA使用POI操作excel
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (新)网络工程师考点串讲与真题详解
  • (译)2019年前端性能优化清单 — 下篇
  • (转)visual stdio 书签功能介绍
  • (转)大型网站的系统架构
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • .DFS.
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET 常见的偏门问题
  • .NET 快速重构概要1
  • .NET_WebForm_layui控件使用及与webform联合使用