简体   繁体   English

使用 tkinter 并排显示多个图像

[英]Displaying multiple images side by side with tkinter

I wrote a program for facial recognition and now I have to make a GUI for it.我写了一个面部识别程序,现在我必须为它制作一个 GUI。 What I need to do is to display 5 images of recognized person.我需要做的是显示 5 张已识别人的图像。 But I can only display one of them.但我只能显示其中一个。 The others are shown empty.其他显示为空。 Here is the code:这是代码:

root = Tk()
root.title("Test state")

def train_button():
    os.system('python3 extract_embeddings.py --dataset dataset --embeddings output/embeddings.pickle --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7')
    os.system('python3 train_model.py --embeddings output/embeddings.pickle --recognizer output/recognizer.pickle --le output/le.pickle')
    messagebox.showinfo("INFO","Training completed")

def select_photo():
    global my_image
    root.filename = filedialog.askopenfilename(initialdir="test",title ="Select a photo",filetypes=(("all files","*.*"),("png files","*.png"),("jpeg files","*.jpeg")))
    output = subprocess.check_output("python3 recognize.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle --image "+root.filename, shell=True)
    output = output.decode('utf-8')
    pic_name = output.split('\n')[0]
     
    my_image = ImageTk.PhotoImage(Image.open("images/"+pic_name+"/"+pic_name+"1.jpeg"))
    my_image_label = Label(image = my_image).grid(row = 1 ,column = 0)

    name_label = Label(text = pic_name).grid(row=2,column=0)

    my_image1 = ImageTk.PhotoImage(Image.open("images/"+pic_name+"/"+pic_name+"2.jpeg"))
    my_image_label1 = Label(image = my_image1).grid(row =1 ,column=1)

    my_image2 = ImageTk.PhotoImage(Image.open("images/"+pic_name+"/"+pic_name+"3.jpeg"))
    my_image_label2 = Label(image = my_image2).grid(row = 1,column = 2)


button1 = Button(root,text = "Train" , command = train_button).grid(row=0 ,column=0)

button2 = Button(root,text = "Recognise from image", command = select_photo).grid(row = 0 ,column=1)



root.mainloop()

This is how the program shows images Resulting program这就是程序显示图像的方式

Thank you for your time感谢您的时间

It is bug in PhotoImage which removes image when it is assigned to local variable in function.这是PhotoImage中的错误,它在将图像分配给 function 中的局部变量时会删除图像。

You have to assing it to global variable (it can be list if you have many images) or assign to widgets which you use to display it - label.photo = image您必须将其分配给全局变量(如果您有很多图像,它可以是列表)或分配给您用来显示它的小部件 - label.photo = image


I can test it but here is version which uses label.photo = image to resolve this problem我可以测试它,但这里是使用label.photo = image来解决这个问题的版本

It also uses for -loop to create labels and keep them on list.它还使用for -loop 创建标签并将它们保留在列表中。

But when you use label.photo = image then list is not necessary.但是,当您使用label.photo = image时,不需要列表。 List is only useful to access labels to remove old labels before you create new labels.列表仅用于在创建新标签之前访问标签以删除旧标签。

import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import filedialog

# --- functions ---

def train_button():
    os.system('python3 extract_embeddings.py --dataset dataset --embeddings output/embeddings.pickle --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7')
    os.system('python3 train_model.py --embeddings output/embeddings.pickle --recognizer output/recognizer.pickle --le output/le.pickle')
    messagebox.showinfo("INFO","Training completed")

def select_photo():
    #global all_labels
    
    root.filename = filedialog.askopenfilename(initialdir="test", title ="Select a photo", filetypes=(("all files","*.*"),("png files","*.png"),("jpeg files","*.jpeg")))
    output = subprocess.check_output("python3 recognize.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle --image "+root.filename, shell=True)
    output = output.decode('utf-8')
    pic_name = output.split('\n')[0]

    # remove previous labels
    for label in all_labels:
        label.destroy()
    
    for number in range(3):
        #filename = f"images/{pic_name}/{pic_name}{number+1}.jpeg" # f-string (Python 3.6+)
        filename = "images/{}/{}{}.jpeg".format(pic_name, pic_name, number+1) # (Python 2.7, 3.0+)
        
        image = ImageTk.PhotoImage(Image.open(filename))
        
        label = tk.Label(image=image)
        label.photo = image   # assign to class variable to resolve problem with bug in `PhotoImage`
        
        label.grid(row=1, column=number)
        
        all_labels.append(label)

# --- main ---

all_labels = []

root = tk.Tk()

button1 = tk.Button(root, text="Train", command=train_button)
button1.grid(row=0, column=0)

button2 = tk.Button(root, text="Recognise from image", command=select_photo)
button2.grid(row=0, column=1)

root.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM