好用————python 库 下载 ,整合在一个小程序 UIUIUI
上图~

import os
import time
import threading
import requests
import subprocess
import importlib
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import urljoinclass PackageInstallerApp:def __init__(self, root):self.root = rootself.root.title("Design By Tim")self.root.geometry("800x600")# 默认设置self.install_dir = r"C:\Users\AAA\Python_Package"self.default_packages = ["numpy", "opencv-python", "pyttsx3"]self.mirrors = ["https://pypi.tuna.tsinghua.edu.cn/simple/","https://mirrors.aliyun.com/pypi/simple/","https://pypi.mirrors.ustc.edu.cn/simple/","https://mirrors.bfsu.edu.cn/pypi/web/simple/","https://mirrors.cloud.tencent.com/pypi/simple/","https://mirrors.nju.edu.cn/pypi/web/simple/","https://mirrors.hit.edu.cn/pypi/web/simple/","https://mirror.sjtu.edu.cn/pypi/web/simple/","https://pypi.doubanio.com/simple/","https://mirrors.zju.edu.cn/pypi/web/simple/","https://mirrors.pku.edu.cn/pypi/simple/","https://mirrors.yun-idc.com/pypi/simple/","https://mirrors.neusoft.edu.cn/pypi/web/simple/","https://mirrors.xjtu.edu.cn/pypi/web/simple/","https://mirrors.huaweicloud.com/repository/pypi/simple/"]# UI控件引用self.start_button = Noneself.cancel_button = None# 创建UIself.create_widgets()def create_widgets(self):# 主框架main_frame = ttk.Frame(self.root, padding="10")main_frame.pack(fill=tk.BOTH, expand=True)# 包列表输入ttk.Label(main_frame, text="要下载的包(逗号分隔):").grid(row=0, column=0, sticky=tk.W)self.pkg_entry = ttk.Entry(main_frame, width=50)self.pkg_entry.grid(row=0, column=1, sticky=tk.EW)self.pkg_entry.insert(0, ",".join(self.default_packages))# 安装目录ttk.Label(main_frame, text="安装目录:").grid(row=1, column=0, sticky=tk.W)self.dir_entry = ttk.Entry(main_frame, width=50)self.dir_entry.grid(row=1, column=1, sticky=tk.EW)self.dir_entry.insert(0, self.install_dir)# 按钮框架btn_frame = ttk.Frame(main_frame)btn_frame.grid(row=2, column=0, columnspan=2, pady=10)# 开始按钮self.start_button = ttk.Button(btn_frame, text="开始下载安装", command=self.start_process)self.start_button.pack(side=tk.LEFT, padx=5)# 取消按钮self.cancel_button = ttk.Button(btn_frame, text="取消", command=self.root.quit)self.cancel_button.pack(side=tk.LEFT, padx=5)# 进度条self.progress = ttk.Progressbar(main_frame, orient=tk.HORIZONTAL, length=500, mode='determinate')self.progress.grid(row=3, column=0, columnspan=2, pady=10)# 状态标签self.status_label = ttk.Label(main_frame, text="准备就绪")self.status_label.grid(row=4, column=0, columnspan=2)# 日志输出ttk.Label(main_frame, text="进度日志:").grid(row=5, column=0, sticky=tk.W)self.log_text = scrolledtext.ScrolledText(main_frame, width=80, height=20, state='normal')self.log_text.grid(row=6, column=0, columnspan=2, sticky=tk.NSEW)# 配置网格权重main_frame.columnconfigure(1, weight=1)main_frame.rowconfigure(6, weight=1)def log_message(self, message):self.log_text.config(state='normal')self.log_text.insert(tk.END, message + "\n")self.log_text.config(state='disabled')self.log_text.see(tk.END)self.root.update()def update_progress(self, value):self.progress['value'] = valueself.root.update()def update_status(self, message):self.status_label.config(text=message)self.root.update()def set_ui_state(self, enabled):state = tk.NORMAL if enabled else tk.DISABLEDself.start_button.config(state=state)self.cancel_button.config(state=state)self.root.update()def start_process(self):# 获取用户输入packages = [pkg.strip() for pkg in self.pkg_entry.get().split(",") if pkg.strip()]self.install_dir = self.dir_entry.get().strip()if not packages:messagebox.showerror("错误", "请输入至少一个包名")returnos.makedirs(self.install_dir, exist_ok=True)# 禁用UIself.set_ui_state(False)self.log_text.config(state='normal')self.log_text.delete(1.0, tk.END)self.log_text.config(state='disabled')self.update_progress(0)# 开始下载安装流程threading.Thread(target=self.download_and_install, args=(packages,), daemon=True).start()def download_and_install(self, packages):overall_success = True # 跟踪整体成功状态try:# 1. 测试镜像源速度self.update_status("正在测试镜像源速度...")self.log_message("="*50)self.log_message("开始测试镜像源速度")fastest_mirrors = self.find_fastest_mirrors()# 2. 下载包self.update_status("开始下载包...")self.log_message("="*50)self.log_message("开始下载包")downloaded_files = []total_packages = len(packages)download_success = Truefor i, package in enumerate(packages):self.update_progress((i/total_packages)*50)mirror = fastest_mirrors[i % len(fastest_mirrors)]success, files = self.download_package(mirror, package)if not success:download_success = Falseoverall_success = Falseself.log_message(f"⚠️ 包 {package} 下载失败,将继续尝试其他包")else:downloaded_files.extend(files)if not download_success:self.log_message("警告: 部分包下载失败")# 3. 安装包self.update_status("开始安装包...")self.log_message("="*50)self.log_message("开始安装包")install_success = Truefor i, file in enumerate(downloaded_files):self.update_progress(50 + (i/len(downloaded_files))*40)if not self.install_package(file):install_success = Falseoverall_success = Falseself.log_message(f"⚠️ 文件 {file} 安装失败")if not install_success:self.log_message("警告: 部分包安装失败")# 4. 验证安装self.update_status("验证安装...")self.log_message("="*50)self.log_message("开始验证安装")verify_success = Truefor i, package in enumerate(packages):self.update_progress(90 + (i/len(packages))*10)if not self.test_installation(package):verify_success = Falseoverall_success = Falseself.log_message(f"⚠️ 包 {package} 验证失败")if not verify_success:self.log_message("警告: 部分包验证失败")self.update_progress(100)# 显示最终结果if overall_success:self.update_status("所有操作成功完成!")self.log_message("="*50)self.log_message("✅ 所有包下载安装完成并验证成功!")messagebox.showinfo("完成", "所有包下载安装完成并验证成功!")else:self.update_status("操作完成,但有错误发生")self.log_message("="*50)self.log_message("⚠️ 操作完成,但部分步骤失败,请检查日志")messagebox.showwarning("完成但有错误", "操作完成,但部分步骤失败,请检查日志了解详情")except Exception as e:self.log_message(f"❌ 发生严重错误: {str(e)}")self.update_status("操作因错误中止")messagebox.showerror("错误", f"处理过程中发生严重错误: {str(e)}")overall_success = Falsefinally:# 重新启用UIself.set_ui_state(True)def find_fastest_mirrors(self):"""找出最快的3个镜像源"""with ThreadPoolExecutor(max_workers=15) as executor:futures = [executor.submit(self.test_mirror_speed, mirror) for mirror in self.mirrors]results = []for future in as_completed(futures):speed, mirror = future.result()if speed != float('inf'):results.append((speed, mirror))self.log_message(f"测试镜像源 {mirror} 速度: {speed:.2f}秒")results.sort()fastest_mirrors = [mirror for speed, mirror in results[:3]]self.log_message(f"最快的3个镜像源: {', '.join(fastest_mirrors)}")return fastest_mirrorsdef test_mirror_speed(self, mirror):"""测试镜像源速度"""try:start = time.time()response = requests.get(urljoin(mirror, "simple/"), timeout=5)if response.status_code == 200:return time.time() - start, mirrorexcept:passreturn float('inf'), mirrordef download_package(self, mirror, package):"""下载单个包"""try:self.log_message(f"正在从 {mirror} 下载 {package}...")cmd = ["python", "-m", "pip", "download", package, "-d", self.install_dir, "-i", mirror, "--trusted-host", mirror.split('//')[1].split('/')[0]]process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)stdout, stderr = process.communicate()if process.returncode == 0:# 获取下载的文件列表files = [f for f in os.listdir(self.install_dir) if f.startswith(package.replace("-", "_"))]self.log_message(f"✅ 成功下载 {package}: {', '.join(files)}")return True, fileselse:self.log_message(f"❌ 下载 {package} 失败: {stderr.strip()}")return False, []except Exception as e:self.log_message(f"❌ 下载 {package} 时发生错误: {str(e)}")return False, []def install_package(self, filename):"""安装单个包"""try:filepath = os.path.join(self.install_dir, filename)self.log_message(f"正在安装 {filename}...")cmd = ["python", "-m", "pip", "install", filepath]process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)stdout, stderr = process.communicate()if process.returncode == 0:self.log_message(f"✅ 成功安装 {filename}")return Trueelse:self.log_message(f"❌ 安装 {filename} 失败: {stderr.strip()}")return Falseexcept Exception as e:self.log_message(f"❌ 安装 {filename} 时发生错误: {str(e)}")return Falsedef test_installation(self, package):"""测试包是否安装成功"""try:# 转换包名(如opencv-python -> opencv_python)import_name = package.replace("-", "_")self.log_message(f"正在验证 {package} 是否可以导入...")module = importlib.import_module(import_name)version = getattr(module, "__version__", "未知版本")self.log_message(f"✅ 验证成功: {package} (版本: {version})")return Trueexcept Exception as e:self.log_message(f"❌ 验证失败: 无法导入 {package} - {str(e)}")return Falseif __name__ == "__main__":root = tk.Tk()app = PackageInstallerApp(root)root.mainloop()
相关文章:
好用————python 库 下载 ,整合在一个小程序 UIUIUI
上图~ import os import time import threading import requests import subprocess import importlib import tkinter as tk from tkinter import ttk, messagebox, scrolledtext from concurrent.futures import ThreadPoolExecutor, as_completed from urllib.parse im…...
OpenVINO教程(五):实现YOLOv11+OpenVINO实时视频目标检测
目录 实现讲解效果展示完整代码 本文作为上篇博客的延续,在之前实现了图片推理的基础上,进一步介绍如何进行视频推理。 实现讲解 首先,我们需要对之前的 predict_and_show_image 函数进行拆分,将图像显示与推理器(pre…...
CentOS的安装以及网络配置
CentOS的下载 在学习docker之前,我们需要知道的就是docker是运行在Linux内核之上的,所以我们需要Linux环境的操作系统,当然了你也可以选择安装ubuntu等操作系统,如果你不想在本机安装的话还可以考虑买阿里或者华为的云服务器&…...
【初级】前端开发工程师面试100题(一)
本题库共计包含100题,考察html,css,js,以及react,vue,webpack等基础知识掌握情况。 HTML基础篇 说说你对HTML语义化的理解? 语义化就是用合适的标签表达合适的内容,比如<header&…...
eplan许可证与防火墙安全软件冲突
在使用EPLAN电气设计软件时,有时会遇到许可证与防火墙或安全软件之间的冲突。这种冲突可能导致许可证无法激活或软件无法正常运行,给用户带来诸多不便。本文将为您解析EPLAN许可证与防火墙/安全软件冲突的原因,并提供解决方案,帮助…...
「Java EE开发指南」用MyEclipse开发EJB 3无状态会话Bean(二)
本教程介绍在MyEclipse中开发EJB 3无状态会话bean,由于JPA实体和EJB 3实体非常相似,因此本教程不涉及EJB 3实体Bean的开发。在本教程中,您将学习如何: 创建EJB 3项目创建无状态会话bean部署并测试bean 在上文中(点击…...
Stable Diffusion秋叶整合包V4独立版Python本地API连接指南
秋叶整合包V4独立版Python本地API连接指南 秋叶整合的Stable Diffusion V4独立版支持通过Python调用本地API实现自动化图像生成。以下是具体操作流程及注意事项: 一、启用API服务 启动器配置 • 在秋叶启动器的 高级选项 中添加以下参数: --api --liste…...
小程序 GET 接口两种传值方式
前言 一般 GET 接口只有两种URL 参数和路径参数 一:URL 参数(推荐方式) 你希望请求: https://serve.zimeinew.com/wx/products/info?id5124接口应该写成这样,用 req.query.id 取 ?id5124: app.get(&…...
深度学习在DOM解析中的应用:自动识别页面关键内容区块
摘要 本文介绍了如何在爬取东方财富吧(https://www.eastmoney.com)财经新闻时,利用深度学习模型对 DOM 树中的内容区块进行自动识别和过滤,并将新闻标题、时间、正文等关键信息分类存储。文章聚焦爬虫整体性能瓶颈,通…...
PyQt6实例_pyqtgraph多曲线显示工具_代码分享
目录 概述 效果 代码 返回结果对象 字符型横坐标 通用折线图工具 工具主界面 使用举例 概述 1 分析数据遇到需要一个股票多个指标对比或一个指标多个股票对比,涉及到同轴多条曲线的显示,所以开发了本工具。 2 多曲线显示部分可以当通用工具使…...
Linux网络编程 多线程Web服务器:HTTP协议与TCP并发实战
问题解答 TCP是如何防止SYN洪流攻击的? 方式有很多种,我仅举例部分: 1、调整内核参数 我们知道SYN洪流攻击的原理就是发送一系列无法完成三次握手的特殊信号,导致正常的能够完成三次握手的信号因为 连接队列空间不足ÿ…...
【Vulkan 入门系列】创建帧缓冲、命令池、命令缓存,和获取图片(六)
这一节主要介绍创建帧缓冲(Framebuffer),创建命令池,创建命令缓存,和从文件加载 PNG 图像数据,解码为 RGBA 格式,并将像素数据暂存到 Vulkan 的 暂存缓冲区中。 一、创建帧缓冲 createFramebu…...
【Git】fork 和 branch 的区别
在 Git 中,“fork” 和 “branch” 是两个不同的概念,它们用于不同的场景并且服务于不同的目的。理解这两者的区别对于有效地使用 Git 进行版本控制非常重要。 1. Fork(分叉) 定义 Fork 是指在 GitHub、GitLab 等代码托管平台上…...
Qt 下载的地址集合
Qt 下载离线安装包 download.qt.io/archive/qt/5.14/5.14.2/ Qt 6 安装下载在线安装包 Index of /qt/official_releases/online_installers/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror...
java将pdf转换成word
1、jar包准备 在项目中新增lib目录,并将如下两个文件放入lib目录下 aspose-words-15.8.0-jdk16.jar aspose-pdf-22.9.jar 2、pom.xml配置 <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId><versi…...
ubuntu下gcc/g++安装及不同版本切换
1. 查看当前gcc版本 $ gcc --version# 查看当前系统中已安装版本 $ ls /usr/bin/gcc*2. 安装新版本gcc $ sudo apt-get update# 这里以版本12为依据(也可以通过源码方式安装,请自行Google!) $ sudo apt-get install -y gcc-12 g…...
缓存与内存;缺页中断;缓存映射:组相联
文章目录 内存(RAM)与缓存(Cache)Memory Management Unit缺页中断 多级缓存缓存替换策略缓存的映射方式 内存(RAM)与缓存(Cache) 缓存: CPU 内部或非常靠近的高速存储&a…...
FPGA入门学习Day1——设计一个DDS信号发生器
目录 一、DDS简介 (一)基本原理 (二)主要优势 (三)与传统技术的对比 二、FPGA存储器 (一)ROM波形存储器 (二)RAM随机存取存储器 (三&…...
微信小程序拖拽排序有效果图
效果图 .wxml <view class"container" style"--w:{{w}}px;" wx:if"{{location.length}}"><view class"container-item" wx:for"{{list}}" wx:key"index" data-index"{{index}}"style"--…...
elasticsearch 查询检索
一、查询方式列举 1、多维度查询 关键词:bool must match {"query": {"bool": {"must": [{"match": {"server_name": "www.test.com"}},{"range": { //时间查询"createTime": …...
WT2000T专业录音芯片:破解普通录音设备信息留存、合规安全与远程协作三大难题
在快节奏的现代商业环境中,会议是企业决策、创意碰撞和战略部署的核心场景。然而,传统会议记录方式常面临效率低、信息遗漏、回溯困难等痛点。如何确保会议内容被精准记录并高效利用?会议室专用录音芯片应运而生,以智能化、高保真…...
【Python 学习笔记】 pip指令使用
系列文章目录 pip指令使用 文章目录 系列文章目录前言安装配置使用pip 管理Python包修改pip下载源 前言 提示:这里可以添加本文要记录的大概内容: 当前文章记录的是我在学习过程的一些笔记和思考,可能存在有误解的地方,仅供大家…...
与Ubuntu相关命令
windows将文件传输到Ubuntu 传输文件夹或文件 scp -r 本地文件夹或文件 ubuntu用户名IP地址:要传输到的文件夹路径 例如: scp -r .\04.py gao192.168.248.129:/home/gao 如果传输文件也可以去掉-r 安装软件 sudo apt-get update 更新软件包列表 sudo apt insta…...
C# 文件读取
文件读取是指使用 C# 程序从计算机文件系统中获取文件内容的过程。将存储在磁盘上的文件内容加载到内存中,供程序处理。主要类型有:文本文件读取(如 .txt, .csv, .json, .xml);二进制文件读取(如 .jpg, .pn…...
leetcode125.验证回文串
class Solution {public boolean isPalindrome(String s) {s s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();for(int i0,js.length()-1;i<j;i,j--){if(s.charAt(i)!s.charAt(j))return false;}return true;} }...
【Android面试八股文】Android系统架构【一】
Android系统架构图 1.1 安卓系统启动 1.设备加电后执行第一段代码:Bootloader 系统引导分三种模式:fastboot,recovery,normal: fastboot模式:用于工厂模式的刷机。在关机状态下,按返回开机 键进…...
NLP高频面试题(五十二)——BERT 变体详解
在现代自然语言处理领域,BERT 系列模型不断演进,衍生出多种变体,它们通过改进预训练任务、模型结构和训练策略,在不同应用场景下取得了更优表现。本文首先概览主要 BERT 变体(如 ALBERT、RoBERTa、ELECTRA、SpanBERT、Transformer-XL 等),随后针对以下几个关键问题逐一展…...
【数据可视化-21】水质安全数据可视化:探索化学物质与水质安全的关联
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
CSS 选择器介绍
CSS 选择器介绍 1. 基本概念 CSS(层叠样式表)是一种用于描述 HTML 或 XML 文档外观的语言。通过 CSS,可以控制网页中元素的布局、颜色、字体等视觉效果。而 CSS 选择器则是用来指定哪些 HTML 元素应该应用这些样式的工具。 2. 基本选择器 …...
【prometheus+Grafana篇】从零开始:Linux 7.6 上二进制安装 Prometheus、Grafana 和 Node Exporter
💫《博主主页》:奈斯DB-CSDN博客 🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了解 💖如果觉得文章对你有所帮…...
