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
该代码块的缩进不是很好,因为原始问题格式的缩进没有那么好。
添加回答
举报