1. 目的
无论是 Windows 还是 Linux 下, 编辑环境变量总是绕不开的一个基本功。也许你已经熟练使用 vim 来查询和就地替换 PATH, 也许你更喜欢在当前 shell 中临时 export 变量, 又或者你更喜欢 Windows 下的图形界面方式的查看和修改环境变量… 本文带来稍微硬核一点的思路: 使用 Python 查询所有的环境变量, 并使用 DearPyGUI 进行显示。
2. 效果
3. 实现思路
获取环境变量
Python 自带的 os.environ()
可以获取环境变量, 不过它只提供当前进程下的结果, 一旦在外部进程中修改了环境变量, os.environ()
并不能感知到。 对于 Windows 来说, 可以从注册表中获取最新的环境变量, 对应的 Python 模块是 winreg
.
分隔环境变量取值
绝大多数环境变量是 key=value 的形式, value 是一个具体的字符串。
少数环境变量如 PATH
, 取值是形如 key=value1;value2;...
或 key=value1:value2:...
形式, 根据不同操作系统,分隔符不同,共同特点是 value 是字符串, 需要 split 后再显示为多行。
界面显示
DearImGUI 提供了很棒的显示思路, DearPyGUI 则封装了 DearImGUI. 按官方 Demo 修改即可初步达到显示效果, 其他则可以自行 hack 源码寻找灵感。
4. 代码实现
安装依赖
pip install dearpygui
编写源码:
env_var_editor.py
:
######################################################################
# Env var editor
# Author: ChrisZZ <imzhuo@foxmail.com>
# Homepage: https://github.com/zchrissirhcz
######################################################################
import dearpygui.dearpygui as dpg
import sledpkg_env_var as spev
import os
import sledpkg as sp
dpg.create_context()
def env_var_value_callback(sender, app_data, user_data):
print(f"[env_var_value_callback] sender: {sender}, \t app_data: {app_data}, \t user_data: {user_data}")
def get_env_vars():
env_var_names = dict(os.environ.items()).keys()
res = dict()
for name in env_var_names:
res[name] = spev.get_env(name)
return res
def get_sorted_env_var_names(env_vars):
env_var_names = sorted(list(env_vars.keys()))
return env_var_names
def get_env_var_value_list(env_var):
if sp.is_windows():
path_delimeter = ';'
else:
path_delimeter = ':'
items = env_var.split(path_delimeter)
res = [_ for _ in items if len(_) > 0]
return res
def save_env_var():
spev.print_path()
spev.append_env('Path', [
R'C:\Users\zz\work\sledpkg'
])
print("-------------")
spev.print_path()
print("-------------")
env_vars = get_env_vars()
path = env_vars['PATH'].split(';')
for item in path:
print(item)
env_var_items = []
selected_env_var_name = None
def show_env_var_value_list(env_var_value_list):
global env_var_items
for item in env_var_items:
dpg.delete_item(item)
env_var_items = []
for env_var_value in env_var_value_list:
item = dpg.add_input_text(default_value=env_var_value, parent=env_var_value_group, callback=env_var_value_callback)
env_var_items.append(item)
def add_env_var_value(sender, app_data, user_data):
print(f"[add_env_var_value] sender: {sender}, \t app_data: {app_data}, \t user_data: {user_data}")
global env_var_items
item = dpg.add_input_text(default_value='', parent=env_var_value_group)#, callback=env_var_value_callback)
env_var_items.append(item)
print(' selected_env_var_name:', selected_env_var_name)
print(' value is:', spev.get_env(selected_env_var_name))
with dpg.window():
with dpg.group(horizontal=True):
env_vars = get_env_vars()
sorted_env_var_names = get_sorted_env_var_names(env_vars)
with dpg.group(horizontal=False):
dpg.add_text('Names')
with dpg.group(horizontal=True):
dpg.add_button(label='+')
dpg.add_button(label='-')
env_var_name_listbox = dpg.add_listbox(sorted_env_var_names, width=300, num_items=40)
with dpg.group(horizontal=False):
dpg.add_text('Values')
with dpg.group(horizontal=True):
dpg.add_button(label='+', callback=add_env_var_value)
dpg.add_button(label='-')
dpg.add_button(label='save', callback=save_env_var)
env_var_value_list = get_env_var_value_list(sorted_env_var_names[0])
env_var_value_group = dpg.add_group(horizontal=False)
dummy = dpg.add_drag_float(label="float", parent=env_var_value_group, width=700)
show_env_var_value_list(env_var_value_list)
def env_var_name_listbox_callback(sender, app_data, user_data):
print(f"[env_var_name_listbox_callback] sender: {sender}, \t app_data: {app_data}, \t user_data: {user_data}")
global selected_env_var_name
selected_env_var_name = app_data
env_var_name = app_data
env_var_value = spev.get_env(env_var_name)
env_var_value_list = get_env_var_value_list(env_var_value)
print(env_var_value)
show_env_var_value_list(env_var_value_list)
with dpg.item_handler_registry(tag="widget handler") as handler:
dpg.set_item_callback(env_var_name_listbox, callback=env_var_name_listbox_callback)
dpg.create_viewport(title='Environment Variable Viewer')
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()