1 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個贊
根據(jù)您的描述,您正在使用完全不同的方法來完成任務(wù)。
我將首先解釋您想要做什么以及為什么它不起作用。
-> 因此,在您要求用戶選擇一個文件并創(chuàng)建folder_dir
和path
后,您希望將所選圖片移動/復(fù)制到變量 描述的位置path
。
問題,
根據(jù)您的需要,您可能就在這里,但我覺得您應(yīng)該使用
filedialog.askopenfile()
而不是filedialog.asksaveasfile()
,因?yàn)槟赡芟M麄冞x擇一個文件,而不是選擇一個文件夾來將文件移動到 - 您似乎已經(jīng)有了目的地folder_dir
。但這又取決于您的需求。重要的一個。在您的代碼中,其中一條注釋顯示:“”“創(chuàng)建位置對象”“”您使用的
f = open(path, "a")
,您沒有在那里創(chuàng)建位置對象。f
只是一個file
以文本追加模式打開的對象 - 如函數(shù)調(diào)用"a"
中的第二個參數(shù)所示open()
。您無法將二進(jìn)制圖像文件寫入文本文件。這就是為什么錯誤消息說它期望將字符串寫入文本文件,而不是二進(jìn)制 I/O 包裝器。
解決方案
很簡單,使用實(shí)際方法移動文件來執(zhí)行任務(wù)。
因此,一旦您有了圖像文件的地址(由用戶在filedialog
上面解釋的中選擇),請注意,正如@Bryan 指出的那樣,picture
變量將始終file handler
是用戶選擇的文件的地址。.name
我們可以使用.txt文件的屬性來獲取所選文件的絕對地址file handler
。
>>> import tkinter.filedialog as fd
>>> a = fd.askopenfile()
# I selected a test.txt file
>>> a
<_io.TextIOWrapper name='C:/BeingProfessional/projects/Py/test.txt' mode='r' encoding='cp1252'>
# the type is neither a file, not an address.
>>> type(a)
<class '_io.TextIOWrapper'>
>>> import os
# getting the absolute address with name attribute
>>> print(a.name)
C:/BeingProfessional/projects/Py/test.txt
# check aith os.path
>>> os.path.exists(a.name)
True
注意:
我們還可以使用filedialog.askopenfilename()它僅返回所選文件的地址,這樣您就不必?fù)?dān)心文件處理程序及其屬性。
我們已經(jīng)有了目的地folder_dir和要給出的新文件名。這就是我們所需要的,源和目的地。這是復(fù)制文件的操作
這三種方法完成相同的工作。根據(jù)需要使用其中任何一個。
import os
import shutil
os.rename("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
shutil.move("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
os.replace("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
請注意,您必須在源參數(shù)和目標(biāo)參數(shù)中包含文件名 (file.foo)。如果更改,文件將被重命名并移動。
另請注意,在前兩種情況下,創(chuàng)建新文件的目錄必須已經(jīng)存在。在 Windows 計(jì)算機(jī)上,具有該名稱的文件一定不存在,否則exception將會引發(fā)錯誤,但os.replace()即使在這種情況下,也會默默地替換文件。
您的代碼已修改
# Creating object from filedialog
picture = filedialog.askopenfile(mode='r', title='Select activity picture', defaultextension=".jpg")
# Check if cancelled
if picture is None:
return
else:
folder_dir = 'main/data/activity_pics'
pic_name = 'rocket_league' #change to desc_to_img_name() later
path = os.path.join(folder_dir, f'{pic_name}')
# Making the folder if it does not exist yet
if not os.path.exists(folder_dir):
os.makedirs(folder_dir)
# the change here
shutil.move(picture.name, path) # using attribute to get abs address
# Check if successful
if os.path.exists(path):
print(f'File saved as {pic_name} in directory {folder_dir}')
self.picture_path = path
該代碼塊的縮進(jìn)不是很好,因?yàn)樵紗栴}格式的縮進(jìn)沒有那么好。
添加回答
舉報(bào)