在python tkinter中与滚动视图相关的顶级窗口中未显示图像

时间:2019-05-20 06:22:39

标签: python tkinter tkinter-canvas

我一直试图制作一个顶层的窗口视图,该窗口收集并显示第10列的文件夹中存在的所有图像。如果图像大于窗口分配的大小,我希望它可以滚动浏览图像。我按照对Scrollable Toplevel Window (tkinter) 的回答正确地将图像添加到画布上并可以滚动它们。但是,就我而言,整个弹出窗口只是空白。这是代码

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

def pop_up_window():
   win = Toplevel()

   vbar = tk.Scrollbar(win, orient = VERTICAL)
   vbar.grid(row = 0, column = 1, sticky = "ns")

   container = tk.Canvas(win, height=300, width=720, scrollregion=(0, 0, 300, 720))
   container.grid(row = 0, column = 0, sticky = "nsew")

   vbar.config(command=container.yview)
   container.config(yscrollcommand=vbar.set)

   path = "D:\\image_collection"
   COLUMNS = 10
   image_count = 0

   for infile in glob.glob(os.path.join(path, '*.jpg')):
      image_count += 1
      r, c = divmod(image_count-1, COLUMNS)
      im = Image.open(infile)
      resized = im.resize((100, 100), Image.ANTIALIAS)
      img_part = ImageTk.PhotoImage(Image.open(infile).resize((100, 100), Image.ANTIALIAS))
      image_in_canvas = container.create_image(r, c, image = img_part)

   win.rowconfigure(0, weight=1)
   win.columnconfigure(0, weight=1)

root = Tk()
button = Button(root, text='Call Pop-up window', command = pop_up_window)
button.place(x = 0, y = 0)
root.mainloop()

我应该进行哪些更改?

2 个答案:

答案 0 :(得分:1)

您需要保留对图像的引用,否则它将被Python垃圾收集。一个简单的更改就可以做到:

import { OnDestroy } from '@angular/core';
import { SubSink } from './sub-sink';

/**
* A class that automatically unsubscribes all observables when 
* the object gets destroyed
*/
export class UnsubscribeOnDestroyAdapter implements OnDestroy {

/**The subscription sink object that stores all subscriptions */
subs = new SubSink();

/**
* The lifecycle hook that unsubscribes all subscriptions 
* when the component / object gets destroyed
*/
ngOnDestroy(): void {
   this.subs.unsubscribe();
}

我还要指出,placeholder = [] def pop_up_window(): ... for infile in glob.glob(os.path.join(path, '*.jpg')): image_count += 1 r, c = divmod(image_count-1, COLUMNS) im = Image.open(infile) img_part = ImageTk.PhotoImage(Image.open(infile).resize((100, 100), Image.ANTIALIAS)) placeholder.append(img_part) image_in_canvas = container.create_image(r, c, image = img_part) 方法采用两个坐标作为args。您当前正在创建它们,就像它们是网格一样,并且不会以您期望的对齐方式显示。

答案 1 :(得分:0)

您的代码可以运行,但是几乎没有问题。如果我忘了注意,我会全部或全部修复,以防万一。

  • 在函数中创建图像时,请始终为其创建引用,因为此处有很多图像,因此您可以为container创建列表。

  • 要根据图像数量不断更新scrollregion,请使用回调函数container将“”绑定到lambda e: scrollregion=container.bbox('all')

这是我对您的pop_up_window函数所做的更改。

...

path = "D:\\image_collection"
COLUMNS = 7
container.img_list = []
column = 0
row = 0

for infile in glob.glob(os.path.join(path, '*.jpg')):
    if column >= COLUMNS: 
        column = 0
        row += 1
    im = Image.open(infile).resize((100, 100), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(im)
    container.img_list.append(img)
    container.create_image(column*100+10, row*100+10, image = img, anchor='nw')
    column += 1

container.bind('<Configure>',lambda e:container.configure(scrollregion=container.bbox('all')))

...