利用python和gpt写一个conda环境可视化管理工具

发布于:2025-02-25 ⋅ 阅读:(15) ⋅ 点赞:(0)

最近在学习python,由于不同的版本之间的差距较大,如果是用环境变量来配置python的话,会需要来回改,于是请教得知可以用conda来管理,但是conda在管理的时候老是要输入命令,感觉也很烦,于是让gpt帮写了一个很简陋的conda环境管理界面(纯属个人学习,不喜勿喷),下面是最终的效果:

1、左侧的激活按钮没什么用

2、中间的输入框是要安装的包名,输入完成之后,点击安装即可把包安装到对应的环境,比如我在ai312对应的输入框中输入numpy,那么就是在a312这个env下面安装numpy的包,其实背后执行的命令就是:conda install numpy -n ai312 -y

3、下面的两个输入框,第一个是环境名称,比如ai312,第二个是python的版本,比如3.8

直接上代码:

import os
import subprocess
import json
import re
import tkinter as tk
from tkinter import messagebox, simpledialog
from tkinter import scrolledtext
import threading

class CondaEnvManager:
    def __init__(self, root):
        self.root = root
        self.root.title("Conda 环境管理器")
        self.root.geometry("600x400")

        # 获取 Conda 路径
        self.conda_path = self.get_conda_path()

        self.env_list_frame = tk.Frame(self.root)
        self.env_list_frame.pack(pady=10, fill=tk.BOTH, expand=True)

        self.create_env_frame = tk.Frame(self.root)
        self.create_env_frame.pack(pady=10)

        self.create_env_label = tk.Label(self.create_env_frame, text="创建新环境:")
        self.create_env_label.grid(row=0, column=0, padx=5)

        self.new_env_name = tk.Entry(self.create_env_frame)
        self.new_env_name.grid(row=0, column=1, padx=5)

        # 新增 Python 版本输入框
        self.python_version_label = tk.Label(self.create_env_frame, text="Python 版本:")
        self.python_version_label.grid(row=1, column=0, padx=5)

        self.python_version_entry = tk.Entry(self.create_env_frame)
        self.python_version_entry.grid(row=1, column=1, padx=5)

        self.create_env_button = tk.Button(self.create_env_frame, text="创建", command=self.create_env)
        self.create_env_button.grid(row=0, column=2, padx=5)

        self.refresh_envs()

        # 日志输出框
        self.log_output = scrolledtext.ScrolledText(self.root, width=70, height=15)
        self.log_output.pack(pady=10, fill=tk.BOTH, expand=True)

    def get_conda_path(self):
        # 提示用户输入 Conda 路径
        while True:
            conda_path = simpledialog.askstring("Conda 路径", "请输入 conda.exe 的完整路径:")
            if not conda_path:
                messagebox.showerror("错误", "Conda 路径不能为空,请重试。")
                continue

            # 检查路径是否有效
            if os.path.isfile(conda_path) and "conda" in conda_path:
                return conda_path
            else:
                messagebox.showerror("错误", f"路径 '{conda_path}' 无效,请重试。")

    def refresh_envs(self):
        for widget in self.env_list_frame.winfo_children():
            widget.destroy()

        try:
            # 使用用户输入的 Conda 路径
            result = subprocess.run([self.conda_path, 'env', 'list', '--json'], capture_output=True, text=True)
            output = result.stdout

            # 提取 JSON 数据
            try:
                json_match = re.search(r'\{.*\}', output, re.DOTALL)
                if not json_match:
                    raise ValueError("No valid JSON data found in the output.")

                json_data = json_match.group(0)
                data = json.loads(json_data)
            except json.JSONDecodeError as e:
                messagebox.showerror("错误", f"解析 JSON 数据失败: {e}")
                return
            except ValueError as e:
                messagebox.showerror("错误", f"提取 JSON 数据失败: {e}")
                return

            envs = data.get('envs', [])

            if not envs:
                messagebox.showinfo("信息", "未找到任何环境。")
                return

            for env in envs:
                env_name = os.path.basename(env)
                env_frame = tk.Frame(self.env_list_frame)
                env_frame.pack(pady=5, fill=tk.X)

                # 激活按钮放到左边
                activate_button = tk.Button(env_frame, text="激活", command=lambda e=env_name: self.activate_env(e))
                activate_button.pack(side=tk.LEFT, padx=5)

                # 环境名称标签
                env_label = tk.Label(env_frame, text=env_name, anchor="w", width=20)
                env_label.pack(side=tk.LEFT, padx=5)

                # 输入框居中并拉长
                package_entry = tk.Entry(env_frame, width=30)
                package_entry.pack(side=tk.LEFT, padx=5, expand=True, fill=tk.X)

                # 安装按钮放到右边
                install_button = tk.Button(env_frame, text="安装", command=lambda e=env_name, p=package_entry: self.start_installation(e, p.get()))
                install_button.pack(side=tk.RIGHT, padx=5)

        except Exception as e:
            messagebox.showerror("错误", f"获取环境失败: {e}")

    def start_installation(self, env_name, package_name):
        if not package_name:
            messagebox.showwarning("警告", "请输入包名。")
            return

        self.log_output.delete(1.0, tk.END)
        threading.Thread(target=self.install_package, args=(env_name, package_name)).start()

    def install_package(self, env_name, package_name):
        try:
            process = subprocess.Popen(
                [self.conda_path, 'install', package_name, '-n', env_name, '-y'],
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                text=True
            )

            for line in process.stdout:
                self.log_output.insert(tk.END, line)
                self.log_output.see(tk.END)

            process.wait()
            messagebox.showinfo("成功", f"在 {env_name} 中安装了 {package_name}。")
        except subprocess.CalledProcessError as e:
            messagebox.showerror("错误", f"安装包失败: {e}")

    def activate_env(self, env_name):
        subprocess.run([self.conda_path, 'activate', env_name], check=True)
        messagebox.showinfo("激活", f"激活环境: {env_name}")

    def create_env(self):
        env_name = self.new_env_name.get().strip()
        python_version = self.python_version_entry.get().strip()  # 获取输入的 Python 版本

        if not env_name:
            messagebox.showwarning("警告", "请输入新环境的名称。")
            return

        if not python_version:
            messagebox.showwarning("警告", "请输入 Python 版本。")
            return

        try:
            subprocess.run([self.conda_path, 'create', '--name', env_name, f'python={python_version}', '-y'], check=True)
            messagebox.showinfo("成功", f"创建新环境: {env_name},Python 版本: {python_version}。")
            self.new_env_name.delete(0, tk.END)
            self.python_version_entry.delete(0, tk.END)  # 清空 Python 版本输入框
            self.refresh_envs()
        except subprocess.CalledProcessError as e:
            messagebox.showerror("错误", f"创建环境失败: {e}")

if __name__ == "__main__":
    root = tk.Tk()
    app = CondaEnvManager(root)
    root.mainloop()

最后通过执行:pyinstaller --onefile --windowed Conda.py,打包成可执行的exe文件即可

启动的时候需要输入conda所在目录(本来我是想通过环境变量来设置,但是代码里面读取不到,于是就采取这种本方法了),比如我的conda安装在:

那么启动时输入: D:/install/anaconda3/condabin/conda.bat

PS:需要先安装  pyinstaller和anaconda(或者miniconda),pyinstaller可以用pip安装(pip install pyinstaller),conda的安装就不在这里说了,跟普通的软件安装一样,一直下一步即可

然后就是如何使用已经创建好的环境了,此处以pycharm为例,比如我创建了一个ai312的环境,那么在conda的安装目录的envs目录下面就会生成一个ai312的目录:

在pycharm里面选择这个python.exe文件: