1 回答

TA貢獻1802條經驗 獲得超6個贊
根據您的描述,您正在使用完全不同的方法來完成任務。
我將首先解釋您想要做什么以及為什么它不起作用。
-> 因此,在您要求用戶選擇一個文件并創建folder_dir
和path
后,您希望將所選圖片移動/復制到變量 描述的位置path
。
問題,
根據您的需要,您可能就在這里,但我覺得您應該使用
filedialog.askopenfile()
而不是filedialog.asksaveasfile()
,因為您可能希望他們選擇一個文件,而不是選擇一個文件夾來將文件移動到 - 您似乎已經有了目的地folder_dir
。但這又取決于您的需求。重要的一個。在您的代碼中,其中一條注釋顯示:“”“創建位置對象”“”您使用的
f = open(path, "a")
,您沒有在那里創建位置對象。f
只是一個file
以文本追加模式打開的對象 - 如函數調用"a"
中的第二個參數所示open()
。您無法將二進制圖像文件寫入文本文件。這就是為什么錯誤消息說它期望將字符串寫入文本文件,而不是二進制 I/O 包裝器。
解決方案
很簡單,使用實際方法移動文件來執行任務。
因此,一旦您有了圖像文件的地址(由用戶在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()它僅返回所選文件的地址,這樣您就不必擔心文件處理程序及其屬性。
我們已經有了目的地folder_dir和要給出的新文件名。這就是我們所需要的,源和目的地。這是復制文件的操作
這三種方法完成相同的工作。根據需要使用其中任何一個。
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")
請注意,您必須在源參數和目標參數中包含文件名 (file.foo)。如果更改,文件將被重命名并移動。
另請注意,在前兩種情況下,創建新文件的目錄必須已經存在。在 Windows 計算機上,具有該名稱的文件一定不存在,否則exception將會引發錯誤,但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
該代碼塊的縮進不是很好,因為原始問題格式的縮進沒有那么好。
添加回答
舉報