我一直在努力教自己tkinter并想制作一个程序,可以在文件夹的目录和子目录中找到所有图片,然后用一个按钮逐个显示它们,或者将文件保存到“是”,“可能”或“跳过”文件夹或只是删除文件。
这是我的代码,试图做到这一点:
# Python 3.4
import os
import tkinter as tk
from tkinter import Frame, Button
from PIL import Image, ImageTk
from send2trash import send2trash
tk_root = tk.Tk()
tk_root.title("Picture Viewer - Do I want to keep this picture?")
file_count = 0
p = path = 'C:\\Users\\MyUserName\\Desktop\\Test\\'
yes = lambda img: os.rename(img, p+'Yes\\Picture_{0}.jpg'.format(file_count))
maybe = lambda img: os.rename(img, p+'Maybe\\Picture_{0}.jpg'.format(file_count))
skip = lambda img: os.rename(img, p+'Skipped\\Picture_{0}.jpg'.format(file_count))
delete = lambda img: send2trash(img) # Note: os.remove('img.jpg') also works
def search(directory):
global file_count
for root, subdirs, files in os.walk(directory):
for file in files:
if os.path.splitext(file)[1].lower() in ('.jpg', '.jpeg'):
img = os.path.join(root, file)
file_count += 1
top_frame = Frame(tk_root)
bottom_frame = Frame(tk_root)
top_frame.pack(side='top')
bottom_frame.pack(side='bottom')
picture = ImageTk.PhotoImage(Image.open(img))
picture = tk.Label(tk_root, image=picture)
picture.pack(side='top')
button_yes = Button(top_frame, text="Yes", command=lambda x=img:yes(x))
button_maybe = Button(top_frame, text="Maybe", command=lambda x=img:maybe(x))
button_skip = Button(top_frame, text="skip", command=lambda x=img:skip(x))
button_delete = Button(bottom_frame, text="Delete", command=lambda x=img:delete(x))
button_yes.pack(side='left')
button_maybe.pack(side='left')
button_skip.pack(side='left')
button_delete.pack(side='bottom')
print('All done!')
search('Test')
然而,问题是在我启动程序之后它根本不能正常工作。它只是将第一张图片“1.jpg”移动到我选择(或删除)的任何文件夹中,如果我尝试对另一张图像进行排序,则会出现以下错误:
FileNotFoundError:[WinError 2]系统找不到该文件 指定:'Test \ Example.jpg' - > 'C:\用户\谷\桌面\测试\也许\ 1.JPG'
也许最重要的是,图像没有正确显示和循环。每次中间只是一个灰色的盒子。我如何让我的程序工作?我知道我需要让图像显得静止,并且需要做一些事情来让程序移动到下一张图片上(所以我没有得到FileNotFoundError来尝试对同一图片进行两次排序),但是在观看教程和阅读文档之后,我不确定该做些什么。
答案 0 :(得分:2)
正如BlackJack所提到的,您的代码一遍又一遍地创建GUI小部件。你需要将它从循环中移出。同样,为了在column1 column2 column3
abc, pqr def,
xyz mno ghi
中显示图片,您无法使用Label
作为picture
对象和ImageTk
对象的名称。
有关更改的建议。您可以使用Generator来获取图像路径/文件名。并且使用常规函数而不是使用lambda。我有兴趣了解它是如何工作的,所以我根据你的代码制作了以下程序。当我测试它时,我有不同的路径,在OSX上工作,所以没有用你的Windows路径测试它(我在这里放入代码)。
Label
修改强>
此代码的一个问题似乎是它贯穿子目录(Yes,Maybe,Skipped)。因此,如果图像在路径中然后移动,您将被呈现两次。
如果您不想遍历Yes,Maybe和Skipped文件夹,可以将import os
import tkinter as tk
from tkinter import Frame, Button
from PIL import Image, ImageTk
tk_root = tk.Tk()
tk_root.title("Picture Viewer - Do I want to keep this picture?")
file_count = 0
p = path = 'C:\\Users\\MyUserName\\Desktop\\Test\\'
def search(directory):
global file_count
for root, subdirs, files in os.walk(directory):
for file in files:
if os.path.splitext(file)[1].lower() in ('.jpg', '.jpeg'):
img = os.path.join(root, file)
file_count += 1
yield img
def next_image():
try:
global photo_path
photo_path = next(path_generator)
photo = ImageTk.PhotoImage(Image.open(photo_path))
picture.configure(image=photo)
picture.image = photo
except StopIteration:
picture.configure(image='', text='All done!')
def move_file(directory):
if not os.path.exists(directory):
os.makedirs(directory)
new_file = directory + 'Picture_{0}.jpg'.format(file_count)
os.rename(photo_path, new_file)
def yes():
move_file(path + 'Yes\\')
next_image()
def maybe():
move_file(path + 'Maybe\\')
next_image()
def skip():
move_file(path + 'Skipped\\')
next_image()
def delete():
# Code for deleting file here
next_image()
top_frame = Frame(tk_root)
bottom_frame = Frame(tk_root)
top_frame.pack(side='top')
bottom_frame.pack(side='bottom')
path_generator = search(p)
photo_path = next(path_generator)
photo = ImageTk.PhotoImage(Image.open(photo_path))
picture = tk.Label(tk_root, image=photo)
picture.image = photo
picture.pack(side='top')
button_yes = Button(top_frame, text="Yes", command=yes)
button_maybe = Button(top_frame, text="Maybe", command=maybe)
button_skip = Button(top_frame, text="skip", command=skip)
button_delete = Button(bottom_frame, text="Delete", command=delete)
button_yes.pack(side='left')
button_maybe.pack(side='left')
button_skip.pack(side='left')
button_delete.pack(side='bottom')
tk_root.mainloop()
功能更改为:
search