环境
windows,python3
序
最近在做一个转换软件,用户指定输入文件后输出该文件转换后的结果。本来是一个比较简单的事情,但在如何让用户指定输入文件这件事上做了一些微小的工作,写出来和大家探讨探讨。
问题
最开始设计的是直接用命令行,比如我的脚本用pyinstaller打包好之后叫c.exe,那用户转换file文件时就可以将file文件拖到c.exe上,相当于命令c.exe file
。
如果用户双击打开了converter.exe,我会告诉用户直接将需要转换的文件拖到图标上。
我以为我写的比较清楚了,但还是有很多用户试图把文件拖进这个黑框框来进行转换。
分析
用户有这种误解很容易理解,毕竟是windows。
于是我开始试图让软件窗口能接受拖放这个动作。没想到看起来很简单的一件事,我还是花了一个上午才找到一种比较合适的解决方案。
方案
最开始发现文件拖进cmd窗口会自动输入文件的绝对路径,尝试用input()
来接收这个路径,但input需要用户手动按enter,而且文件拖放之后窗口直接失去焦点了,也就是说用户需要做的是1拖放文件、2点击窗口获得焦点、3按下enter,显然不是优秀的用户体验。
后来想要不用GUI吧,还能弹文件选择窗口让用户自己选文件,多好。试着用tkinter做了一个,结果打包出来的文件大了2m多不说,启动速度直接从1秒左右变成了5秒,遂放弃。
下决心想要做这个功能,为了省去用户按enter,用msvcrt.getch()
来循环接收输入,然后用超时模块实现接收到拖放之后立即执行转换。代码如下:
import sys
from func_timeout import func_set_timeout, FunctionTimedOut
import msvcrt
File_name = ''
@func_set_timeout(0.1)
def get_input_file(pre_str=''):
global File_name
File_name = pre_str
while True:
File_name += msvcrt.getwch()
if __name__ == '__main__':
if len(sys.argv) != 2:
print('请拖入需要转换的文件')
first_chr = msvcrt.getwch()
try:
get_input_file(first_chr)
except FunctionTimedOut:
convert(File_name.strip('"'))
else:
convert(sys.argv[1])
要注意的是如果路径里包含空格,windows会自动给路径加上引号,所以要strip掉,另外getch()
拿到的bytestring需要decode,而这里用的getwch()
拿到的是unicode,不用转换。
当然,拿到路径之后需要判断文件是否存在或文件是否合法等等,由于和本文无关,就省略了。
网友评论