美文网首页
python命令行窗口获取拖放文件路径

python命令行窗口获取拖放文件路径

作者: KayFelicities | 来源:发表于2019-10-25 09:23 被阅读0次

    环境

    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,不用转换。
    当然,拿到路径之后需要判断文件是否存在或文件是否合法等等,由于和本文无关,就省略了。

    参考

    how-to-enter-a-input-without-pressing-enter

    相关文章

      网友评论

          本文标题:python命令行窗口获取拖放文件路径

          本文链接:https://www.haomeiwen.com/subject/awojvctx.html