导读:还在为 GUI 布局代码头疼?本文带你体验国产可视化 Python 编程工具 PyMe,无需手写一行界面代码,通过简单的拖拽操作,快速构建一个支持文件拖拽导入、手动选择和列表展示的桌面应用。
继前文分享 国产可视化Python工具 PyMe 初体验:拖拖拽拽做桌面应用后,今天我将继续分享由 PyMe 作者开发的一个示例程序。该程序结合 PyMe 可视化 GUI 布局功能与 windnd 库,以极少量代码实现了文件的拖拽导入功能。
本实例程序主要功能包括:
下载安装 PyMe(见PyMe官网,或参考前文国产可视化Python工具 PyMe 初体验:拖拖拽拽做桌面应用)。
注:PyMe 已内置了常用库,也可自行安装额外需要的库。
在 PyMe 的可视化设计器中,从左侧控件栏拖拽以下控件到设计区域,并按照下表设置属性:
Frame_1
Label_1
Resources/文件夹.pngButton_1
界面设计完成后的效果如下:

界面说明:
PyMe 会自动生成以下文件结构:
拖拽文件.py | |
拖拽文件_cmd.py | 事件处理文件 |
拖拽文件_sty.py | |
Fun.py | |
EXUIControl.py |
打开 拖拽文件_cmd.py 文件,编写事件处理函数:
#coding=utf-8import sysimport osfrom os.path import abspath, dirnamesys.path.insert(0,abspath(dirname(__file__)))import tkinterfrom tkinter import *import Funimport windnd # 导入拖拽文件支持库# ============================================# 全局变量(可根据需要扩展)# ============================================ElementBGArray = {}ElementBGArray_Resize = {}ElementBGArray_IM = {}# ============================================# 窗体加载事件# ============================================defForm_1_onLoad(uiName):""" 界面加载时执行的函数 为 Frame_1 注册拖拽文件事件 """# 获取 Frame_1 控件 Frame_1 = Fun.GetElement(uiName, "Frame_1")# 为 Frame_1 注册拖拽事件,指定回调函数为 get_files windnd.hook_dropfiles(Frame_1, func=get_files)# 可选:在控制台打印提示信息 print("程序已启动,请拖拽文件到窗口")# ============================================# 拖拽文件回调函数# ============================================defget_files(files):""" 处理拖拽文件的回调函数 参数 files: 拖拽的文件列表(每个元素是字节串) """for file_bytes in files:# Windows 系统使用 GBK 编码,需要解码 file_path = file_bytes.decode('gbk')# 将文件路径添加到 ListBox 中 Fun.AddItemText('拖拽文件', "ListBox_1", file_path, "end")# 可选:在控制台打印日志 print(f"已添加文件: {file_path}")# ============================================# 按钮点击事件# ============================================defButton_1_onCommand(uiName, widgetName):""" 按钮点击事件处理函数 打开文件选择对话框,将选择的文件添加到列表 """# 打开文件选择对话框# 参数:标题、文件类型过滤、初始目录 openPath = Fun.OpenFile( title="选择文件", filetypes=[('所有文件', '*.*')], initDir='' )# 如果用户选择了文件(没有取消)if openPath:# 将文件路径添加到 ListBox Fun.AddItemText(uiName, "ListBox_1", openPath, "end")# 更新状态 print(f"已选择文件: {openPath}")# ============================================# 文件夹图标点击事件(可选)# ============================================defLabel_1_onButton1(event, uiName, widgetName, threadings=0):""" 文件夹图标点击事件 点击图标同样打开文件选择对话框 """# 复用按钮的点击逻辑 Button_1_onCommand(uiName, widgetName)Fun.GetElement(uiName, elementName)作用: 获取指定名称的控件对象
参数:
uiName:界面类名,通常为 self.uiNameelementName:控件名称,如 "Frame_1"、"Button_1"返回值: 控件对象
示例:
Frame_1 = Fun.GetElement(uiName, "Frame_1")Button_1 = Fun.GetElement(uiName, "Button_1")ListBox_1 = Fun.GetElement(uiName, "ListBox_1")windnd.hook_dropfiles(widget, func)这是实现文件拖拽功能的核心,实现代码之所以简单,全靠这个库。
作用: 为控件注册拖拽文件事件
参数:
widget:要注册事件的控件func:回调函数,参数为拖拽的文件列表注意: 回调函数的参数 files 是一个列表,每个元素是 GBK 编码的字节串,需要用 decode('gbk') 解码。
Fun.AddItemText(uiName, elementName, text, index)作用: 向 ListBox 或 ComboBox 添加一个选项
参数:
uiName:界面类名elementName:控件名称text:要添加的文本index:插入位置,通常为 "end" 表示末尾Fun.OpenFile(title, filetypes, initDir)作用: 打开文件选择对话框
参数:
title:对话框标题filetypes:文件类型过滤列表,如 [('所有文件', '*.*')]initDir:初始目录返回值: 选择的文件路径,如果取消则返回空字符串
点击 PyMe 工具栏上的运行按钮(绿色三角形),或者命令行执行
python 拖拽文件.py运行效果:

拖拽文件到 Frame 区:


现象: 拖拽的文件路径中文显示乱码
原因: Windows 系统使用 GBK 编码,而 Python 内部使用 Unicode
解决: 使用 decode('gbk') 解码
file_path = file_bytes.decode('gbk')原因:
windnd 模块hook_dropfiles 注册事件解决:
import windnd# 注意:func=get_files 后面不要加括号windnd.hook_dropfiles(Frame_1, func=get_files)原因: 在事件处理函数中直接使用控件名称字符串,而不是变量
解决: 使用 Fun.GetElement(uiName, "控件名称") 获取控件
Frame_1 = Fun.GetElement(uiName, "Frame_1") # 正确# Frame_1 = uiName.Frame_1 # 错误原因: 可能使用了错误的添加方法
解决: 使用 Fun.AddItemText 方法
Fun.AddItemText(uiName, "ListBox_1", file_path, "end")可根据个人需要扩展相关功能:
在拖拽回调或按钮事件中添加文件类型判断:
defButton_1_onCommand(uiName, widgetName):# 只显示图片文件 filetypes = [ ('图片文件', '*.jpg;*.jpeg;*.png;*.gif'), ('所有文件', '*.*') ] openPath = Fun.OpenFile("选择图片", filetypes, '')if openPath:# 检查扩展名 ext = os.path.splitext(openPath)[1].lower()if ext in ['.jpg', '.jpeg', '.png', '.gif']: Fun.AddItemText(uiName, "ListBox_1", openPath, "end")else: Fun.MessageBox("请选择图片文件", "提示")进一步处理文件,显示更多信息:
import osimport datetimedefget_files(files):for file_bytes in files: file_path = file_bytes.decode('gbk')if os.path.exists(file_path):# 获取文件信息 file_size = os.path.getsize(file_path) file_name = os.path.basename(file_path) mod_time = os.path.getmtime(file_path) mod_time_str = datetime.datetime.fromtimestamp(mod_time).strftime('%Y-%m-%d %H:%M:%S')# 格式化文件大小if file_size < 1024: size_str = f"{file_size} B"elif file_size < 1024 * 1024: size_str = f"{file_size/1024:.2f} KB"else: size_str = f"{file_size/(1024*1024):.2f} MB"# 组合显示信息 file_info = f"{file_name} ({size_str}) - 修改时间: {mod_time_str}" Fun.AddItemText('拖拽文件', "ListBox_1", file_info, "end")添加一个"清空"按钮:
界面设计:再添加一个 Button 控件,命名为 Button_Clear,文本设为"清空列表"
事件处理:
defButton_Clear_onCommand(uiName, widgetName):""" 清空列表按钮点击事件 """ Fun.Clear(uiName, "ListBox_1") print("列表已清空")添加一个标签显示当前文件数量:
界面设计:添加一个 Label 控件,命名为 label_count,初始文本"文件数量:0"
事件处理:
defupdate_file_count(uiName):"""更新文件数量显示""" listbox = Fun.GetElement(uiName, "ListBox_1") count = listbox.size() Fun.SetText(uiName, "label_count", f"文件数量:{count}")# 在添加文件后调用此函数defget_files(files):for file_bytes in files: file_path = file_bytes.decode('gbk') Fun.AddItemText('拖拽文件', "ListBox_1", file_path, "end") update_file_count('拖拽文件')本文通过一个简单的文件拖拽程序,展示了 PyMe 可视化编程工具的特色。无需手写一行界面代码,仅通过拖拽控件和少量业务逻辑代码,就完成了一个桌面应用。
PyMe 是一款国产可视化 Python 编程工具,它允许开发者通过拖拽控件的方式快速构建图形用户界面(GUI),并自动生成对应的 Python 代码。PyMe 基于Tkinter 封装,提供了丰富的自定义控件,如圆角编辑框、日历选择器、开关按钮等,大大降低了GUI开发的难度。
作者简介:码上工坊,探索用编程为己赋能,定期分享编程知识和项目实战经验。持续学习、适应变化、记录点滴、复盘反思、成长进步。
重要提示:本文主要是记录自己的学习与实践过程,所提内容或者观点仅代表个人意见,只是我以为的,不代表完全正确,欢迎交流讨论。