【问题标题】:How to display two images on the same Tkinter Toplevel () window如何在同一个 Tkinter Toplevel() 窗口上显示两个图像
【发布时间】:2016-12-25 02:00:59
【问题描述】:

所以我正在构建一个可以比较两张照片的应用程序。我在屏幕左侧放了一个列表框,在屏幕右侧放了两张照片。列表框下方有三个按钮,用于将图片放置在某个标题下(图 1 或图 2)。它可以工作,但我只能将一张照片放在图片 1 和图片 2 上 - 如果我选择一张照片并将其放在图片 1 下,然后选择另一张照片并将其放在图片 2 下,第一张就会消失。

为了更好地理解我的问题,这是我的应用程序中的照片浏览功能。

from Tkinter import *
import tkMessageBox
from PIL import ImageTk, Image

def photo_browse ():

    def add_photo (screen, column_num):

        if not "pic" in globals ():
            tkMessageBox.showerror ("Error!", "No picture selected!")
            screen.lift ()
        else:
            screen.image = pic
            can = Label (screen, image = pic)
            can.grid (row = 0, column = column_num)
            Label (screen, text = chosen_photo).grid (row = 1, column = column_num)

    def selection_listbox (evt):

        global chosen_photo
        chosen_photo = str (photo_listbox.get (photo_listbox.curselection ()))
        image_location = "Pics/" + chosen_photo
        global pict
        pict = Image.open (image_location)
        global pic
        pic = ImageTk.PhotoImage (pict)

    import glob

    photo_browse_screen = Toplevel ()
    photo_browse_screen.title ("Photo browse")
    photo_browse_screen.geometry ("1000x600")
    photo_browse_screen.resizable (0, 0)
    photo_listbox = Listbox (photo_browse_screen, width = 50, height = 35)
    photo_listbox.grid (columnspan = 3)
    photo_listbox.bind ('<<ListboxSelect>>', selection_listbox)
    name_list = glob.glob ("Pics/*.jpg")
    name_list = [i [6:] for i in name_list]
    name_list.sort ()
    n = 1
    m = 0
    for i in name_list:
        photo_listbox.insert (n, name_list [m])
        n += 1
        m += 1
    Button (photo_browse_screen, text = "PIC 1", command = lambda: add_photo (photo_browse_screen, 4)).grid (row = 1, column = 0)
    Button (photo_browse_screen, text = "PIC 2", command = lambda: add_photo (photo_browse_screen, 5)).grid (row = 1, column = 1)
    Button (photo_browse_screen, text = "EXIT", command = photo_browse_screen.destroy).grid (row = 1, column = 2)
    can_pic_1 = Label (photo_browse_screen, text = "Pic 1", font= "-weight bold")
    can_pic_1.grid (row = 0, column = 4, padx = (200, 100), sticky = N)
    can_pic_2 = Label (photo_browse_screen, text = "Pic 2", font= "-weight bold")
    can_pic_2.grid (row = 0, column = 5, padx = (100, 150), sticky = N)

root = Tk ()
root.title ("Main menu")
root.geometry ("1000x600")
root.resizable (0, 0)
main_menu = Menu (root)

photos_menu = Menu (main_menu, tearoff = 0)

main_menu.add_cascade (label = "Photos", menu = photos_menu)
photos_menu.add_command (label = "Browse photos", command = photo_browse)

root.config (menu = main_menu)

root.mainloop ()

在之前的功能(添加照片)中,我将照片调整为 308x440 尺寸,以便它们完全适合此窗口。

查看我的代码后,我几乎可以肯定 global 变量导致了这个问题,所以如果有人可以提供替代方案,我将不胜感激。

【问题讨论】:

  • 您是否尝试过将它们放入框架等单独的容器中?
  • 我没有...我该怎么做?据我所知,Frame 没有将图像放入其中的选项...

标签: python image tkinter listbox global-variables


【解决方案1】:

我使用的是 python 3.4,所以我不能 100% 确定这对你有用(对我来说 Tkinter 就是 tkinter)

当我想使用多张图片时,我将它们全部添加到列表中,之后您无需对列表执行任何操作

这一直对我有用,我也遇到了你描述的同样的问题,但没有列表

from Tkinter import *
import tkMessageBox
from PIL import ImageTk, Image

global all_images
all_images = []

def photo_browse ():
    def selection_listbox (evt):    
        global chosen_photo
        chosen_photo = str (photo_listbox.get (photo_listbox.curselection ()))
        image_location = "Pics/" + chosen_photo
        global pict
        pict = Image.open (image_location)
        global pic
        pic = ImageTk.PhotoImage (pict)

        # adding all the images to a list has worked for me in the past
        global all_images
        all_images = all_images + [chosen_photo, pic, pict]

【讨论】:

  • 效果很好,谢谢!我仍然是这方面的初学者,但是通过这个示例我看到了全局变量可能导致的问题,并且我将来会尽力避免它们!
最近更新 更多