環(huán)境
windows艺演,python3
序
最近在做一個(gè)轉(zhuǎn)換軟件市咆,用戶指定輸入文件后輸出該文件轉(zhuǎn)換后的結(jié)果汗捡。本來(lái)是一個(gè)比較簡(jiǎn)單的事情虽抄,但在如何讓用戶指定輸入文件這件事上做了一些微小的工作,寫(xiě)出來(lái)和大家探討探討辛燥。
問(wèn)題
最開(kāi)始設(shè)計(jì)的是直接用命令行筛武,比如我的腳本用pyinstaller打包好之后叫c.exe,那用戶轉(zhuǎn)換file文件時(shí)就可以將file文件拖到c.exe上挎塌,相當(dāng)于命令c.exe file
徘六。
如果用戶雙擊打開(kāi)了converter.exe,我會(huì)告訴用戶直接將需要轉(zhuǎn)換的文件拖到圖標(biāo)上榴都。
我以為我寫(xiě)的比較清楚了硕噩,但還是有很多用戶試圖把文件拖進(jìn)這個(gè)黑框框來(lái)進(jìn)行轉(zhuǎn)換。
分析
用戶有這種誤解很容易理解缭贡,畢竟是windows。
于是我開(kāi)始試圖讓軟件窗口能接受拖放這個(gè)動(dòng)作辉懒。沒(méi)想到看起來(lái)很簡(jiǎn)單的一件事阳惹,我還是花了一個(gè)上午才找到一種比較合適的解決方案。
方案
最開(kāi)始發(fā)現(xiàn)文件拖進(jìn)cmd窗口會(huì)自動(dòng)輸入文件的絕對(duì)路徑眶俩,嘗試用input()
來(lái)接收這個(gè)路徑莹汤,但input需要用戶手動(dòng)按enter,而且文件拖放之后窗口直接失去焦點(diǎn)了颠印,也就是說(shuō)用戶需要做的是1拖放文件纲岭、2點(diǎn)擊窗口獲得焦點(diǎn)、3按下enter线罕,顯然不是優(yōu)秀的用戶體驗(yàn)止潮。
后來(lái)想要不用GUI吧,還能彈文件選擇窗口讓用戶自己選文件钞楼,多好喇闸。試著用tkinter做了一個(gè),結(jié)果打包出來(lái)的文件大了2m多不說(shuō),啟動(dòng)速度直接從1秒左右變成了5秒燃乍,遂放棄唆樊。
下決心想要做這個(gè)功能,為了省去用戶按enter刻蟹,用msvcrt.getch()
來(lái)循環(huán)接收輸入逗旁,然后用超時(shí)模塊實(shí)現(xiàn)接收到拖放之后立即執(zhí)行轉(zhuǎn)換。代碼如下:
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('請(qǐng)拖入需要轉(zhuǎn)換的文件')
first_chr = msvcrt.getwch()
try:
get_input_file(first_chr)
except FunctionTimedOut:
convert(File_name.strip('"'))
else:
convert(sys.argv[1])
要注意的是如果路徑里包含空格舆瘪,windows會(huì)自動(dòng)給路徑加上引號(hào)片效,所以要strip掉,另外getch()
拿到的bytestring需要decode介陶,而這里用的getwch()
拿到的是unicode堤舒,不用轉(zhuǎn)換。
當(dāng)然哺呜,拿到路徑之后需要判斷文件是否存在或文件是否合法等等舌缤,由于和本文無(wú)關(guān),就省略了某残。