python - 如何使用 tkinter GUI 在 python 中依次显示图像

标签 python user-interface tkinter

我的代码主要有两个问题:
1)它显示错误“不存在这样的目录或文件”,尽管我对另一个程序的图像使用了相同的路径(尽管我只指定了一个图像的常量路径)以及图像文件、该程序和另一个程序,都在同一个工作目录
2)它不等待等待函数,它只是执行到16,然后打开GUI。我希望它一一显示所有图像,并且仅当我按“下一步”按钮时才更改
请建议对代码进行任何更改,以满足上述要求。
我在 Windows 10 系统中安装了 Python 3.5.2。
提前致谢

import sys
import tkinter as tk
from PIL import Image,ImageTk,ImageFilter,ImageOps
from msvcrt import getch

def wait():
    getch()
    return

def classify_obj():
    print("In Development")
    return

src = "ímages/"

root = tk.Tk()
root.wm_title("Classify Image")

for i in range(1,17):
    frame1 = tk.Frame(root, width=500, height=400, bd=2)
    frame1.grid(row=1, column=0)
    cv1 = tk.Canvas(frame1, height=390, width=490, background="white", bd=1, relief=tk.RAISED)
    cv1.grid(row=1,column=0)
    im = Image.open(src+str(i)+".jpg")
    if (490-im.size[0])<(390-im.size[1]):
        width = 490
        height = width*im.size[1]/im.size[0]
    else:
        height = 390
        width = height*im.size[0]/im.size[1]
    im.thumbnail((width, height), Image.ANTIALIAS)
    photo = ImageTk.PhotoImage(im)
    cv1.create_image(0, 0, image=photo, anchor='nw')
    claButton = tk.Button(master=root, text='Classify', height=2, width=10, command=classify_obj)
    claButton.grid(row=0, column=1, padx=2, pady=2)
    frame2 = tk.Frame(root, width=500, height=400, bd=1)
    frame2.grid(row=1, column=1)
    cv2 = tk.Canvas(frame2, height=390, width=490, bd=2, relief=tk.SUNKEN)
    cv2.grid(row=1,column=1)
    broButton = tk.Button(master=root, text='Next', height=2, width=8, command=wait)
    broButton.grid(row=0, column=0, padx=2, pady=2)
    print(i)

tk.mainloop()

最佳答案

因此,按照您尝试的方式获取下一张图像的一个大问题是 for 循环。发生的事情是你告诉 python 检查该循环中的所有内容并执行这些功能。

我认为一个更好的方法是首先将此程序创建为。这样我们就可以避免在程序的任何地方调用全局变量。然后在 __init__ 的所述类中,我们创建图像文件夹内每个照片图像的列表。 (注意:我仅使用 .jpg 图像进行了测试)。现在我们有了所有文件名的列表,然后我们可以使用该列表来计算我们正在处理的图像文件的数量。通过这个计数,我们可以创建一个计数器,让我们选择列表中的下一个索引,从而选择所述列表中的下一个图像。

通过将所有变量创建为类的属性,我们可以与这些属性进行交互,而无需将它们声明为全局属性。

看下面的例子。只需将 src 变量更改为您的文件路径即可。 如果您的文件夹位于主 Python 工作区中,请记住在文件路径中使用 . 。示例:我在与 main.py 相同的目录中有一个名为 TestImages 的文件夹,因此我可以创建此变量:src = "./TestImages/".

看一下下面的代码:

import tkinter as tk
from PIL import Image,ImageTk
import os


class ImageClassifyer(tk.Frame):


    def __init__(self, parent, *args, **kwargs):

        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.root = parent
        self.root.wm_title("Classify Image")   
        src = "./TestImages/"

        self.list_images = []
        for d in os.listdir(src):
            self.list_images.append(d)

        self.frame1 = tk.Frame(self.root, width=500, height=400, bd=2)
        self.frame1.grid(row=1, column=0)
        self.frame2 = tk.Frame(self.root, width=500, height=400, bd=1)
        self.frame2.grid(row=1, column=1)

        self.cv1 = tk.Canvas(self.frame1, height=390, width=490, background="white", bd=1, relief=tk.RAISED)
        self.cv1.grid(row=1,column=0)
        self.cv2 = tk.Canvas(self.frame2, height=390, width=490, bd=2, relief=tk.SUNKEN)
        self.cv2.grid(row=1,column=0)

        claButton = tk.Button(self.root, text='Classify', height=2, width=10, command=self.classify_obj)
        claButton.grid(row=0, column=1, padx=2, pady=2)
        broButton = tk.Button(self.root, text='Next', height=2, width=8, command = self.next_image)
        broButton.grid(row=0, column=0, padx=2, pady=2)

        self.counter = 0
        self.max_count = len(self.list_images)-1
        self.next_image()

    def classify_obj(self):
        print("In Development")

    def next_image(self):

        if self.counter > self.max_count:
            print("No more images")
        else:
            im = Image.open("{}{}".format("./TestImages/", self.list_images[self.counter]))
            if (490-im.size[0])<(390-im.size[1]):
                width = 490
                height = width*im.size[1]/im.size[0]
                self.next_step(height, width)
            else:
                height = 390
                width = height*im.size[0]/im.size[1]
                self.next_step(height, width)

    def next_step(self, height, width):
        self.im = Image.open("{}{}".format("./TestImages/", self.list_images[self.counter]))
        self.im.thumbnail((width, height), Image.ANTIALIAS)
        self.root.photo = ImageTk.PhotoImage(self.im)
        self.photo = ImageTk.PhotoImage(self.im)

        if self.counter == 0:
            self.cv1.create_image(0, 0, anchor = 'nw', image = self.photo)

        else:
            self.im.thumbnail((width, height), Image.ANTIALIAS)
            self.cv1.delete("all")
            self.cv1.create_image(0, 0, anchor = 'nw', image = self.photo)
        self.counter += 1


if __name__ == "__main__":
    root = tk.Tk() 
    MyApp = ImageClassifyer(root)
    tk.mainloop()

关于python - 如何使用 tkinter GUI 在 python 中依次显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44629267/

相关文章:

python - 运行所有 Python bdd 行为和单元测试

javascript - Ext.form.FormPanel 和表单提交

python - 如何停止 Tkinter 文本小部件在字体更改时调整大小?

python - 如何将 pytest fixture 应用于多个文件

python - 从 Python 中的多维数组中删除行

python - 显示 pandas 列 AD 的 NaN

Java-选项卡上的按键监听器不起作用

java - 编辑 JTextField 时是否可以禁用 JComboBox?

python - 使用 Tkinter 在未知长度的可迭代中为每个项目创建一个条目

python - tkinter 在窗口关闭之前不会打印