2010-07-29 14 views
5

Po uruchomieniu programu pojawia się płótno, ale obraz nie jest wyświetlany.Nie można wyświetlić obrazu w urządzeniu Tkinter

canvas = Canvas(frame, width = 128, height = 128, bg= 'white') 
    image_data = Image.open('NoArt.gif') 
    ppm_f = ImageTk.PhotoImage(image_data) 
    canvas.create_image(0, 0, image = ppm_f, anchor = NW) 
    canvas.pack(side=BOTTOM) 

Jakieś pomysły?

PS.

mam PIL ver 1.6, Pythona 2.6 i wersji Tkinter, że pochodzi z Pythona 2.6

Odpowiedz

8

Ok, zdobione. Najwyraźniej ze względu na sposób, w jaki pyton radzi sobie z usuwaniem śmieci, zdjęcia zostają po prostu usunięte. Wymagane jest odniesienie do obrazu w zasięgu globalnym. Jest to kod pracy w końcu skończyło się używając:

self.photo = PhotoImage(file="noart.ppm") 
    self.Artwork = Label(self.frame, image=self.photo) 
    self.Artwork.photo = self.photo 
    self.Artwork.pack() 

self.Artwork.photo = self.photo że jest ważną częścią. Zapewnia to, że obraz zostanie wyświetlony.

1

Jeśli ktoś kiedykolwiek ma podobny problem, można spróbować tego sztywno rozwiązanie:

import Image 
import Tkinter as tk 

def cleanhex(x): 
    return str(hex(x))[-2:] 

def renderimage(target,data,w,h): 
    canvas = tk.Canvas(target,width=w,height=h) 
    canvas.pack() 
    for x in range(w): 
     for y in range(h): 
      c = "#" + cleanhex(data[x,y][0]) + cleanhex(data[x,y][1]) + cleanhex(data[x,y][2]) 
      canvas.create_line(x,y,x+1,y+1,fill=c) 

im = Image.open("whatever.whatever") 
renderimage(root,im.load(),im.size[0],im.size[1]) 
+0

Czy możesz wyjaśnić, co dokładnie robisz? –

+0

Ładowanie obrazu i rysowanie go piksel po pikselu. Prawdopodobnie nie jest to coś, czego powinieneś używać w praktyce (istnieją inne, bardziej zoptymalizowane funkcje, które istnieją w Tkinter), ale działa. –

0

Jak wspomniano w this very answer i this more popular question & answer a także w effbot.page

Po dodaniu PhotoImage lub innego Obiekt obrazu do widgetu Tkinter, należy zachować własne odniesienie do obiektu obrazu. Jeśli tego nie zrobisz, obraz nie zawsze się wyświetli.

Problem polega na tym, że interfejs Tkinter/Tk nie obsługuje poprawnie odnośników do obiektów Image; Widżet Tk będzie zawierał odniesienie do obiektu wewnętrznego , ale Tkinter tego nie robi. Gdy narzędzie do zbierania śmieci Python odrzuca obiekt Tkinter, Tkinter mówi TK, aby zwolnił obraz. Ale ponieważ obraz jest używany przez widget, Tk go nie niszczy. Całkowicie nie . To po prostu wygasza obraz, dzięki czemu jest całkowicie przezroczysty ...

Rozwiązaniem jest, aby upewnić się zachować odniesienie do obiektu Tkinter ,

Na przykład image w kodzie poniżej won’t always show up, jeśli w ogóle ponieważ nie jest zadeklarowana w zakresie globalnym:

import tkinter as tk 

root = tk.Tk() 

def show_image(): 
    img_label = tk.Label(root) 
    image = tk.PhotoImage(file="test.png") 
    img_label['image'] = image 

    img_label.pack() 


show_image() 
root.mainloop() 

natomiast w poniższym przykładzie img_label.image jest zadeklarowana globalnie jako atrybut dołączony do naszego bardzo img_label w tym przykładzie, a will be shown:

import tkinter as tk 

root = tk.Tk() 

def show_image(): 
    img_label = tk.Label(root) 
    img_label.image = tk.PhotoImage(file="test.png") 
    img_label['image'] = img_label.image 

    img_label.pack() 


show_image() 
root.mainloop() 

Jest jednak nadal dziwnie img_label nie jest zadeklarowana globalnie zarówno. Mniej kłopotliwym sposobem byłoby dodanie global image jako pierwszej linii do show_image.

Powiązane problemy