如何让我的tkinter图片浏览器工作?

时间:2015-12-30 10:17:59

标签: python python-3.x tkinter python-imaging-library

我一直在努力教自己tkinter并想制作一个程序,可以在文件夹的目录和子目录中找到所有图片,然后用一个按钮逐个显示它们,或者将文件保存到“是”,“可能”或“跳过”文件夹或只是删除文件。

以下是我试图让它看起来像: enter image description here

这是我的代码,试图做到这一点:

# 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来尝试对同一图片进行两次排序),但是在观看教程和阅读文档之后,我不确定该做些什么。

1 个答案:

答案 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