Mehrere Bilder im Canvas?

Fragen zu Tkinter.
Antworten
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Hallo,
Ich versuche mir einkleines programm zu erstellen, welches mehrere Bilder untereinander darstellen kann. Die Bild-Koordinaten sollten hierbei vom ersten bis zum letzten Bild fortlaufend sein.
Darueberhinaus normiere ich jedes Bild auf eine Breite von 300 pixeln.

Ich verwende hierzu Canvas.create_image jedoch wird am Ende immer nur das letzte Bild ganz unten angezeigt.

Wo liegt mein Fehler?

Code: Alles auswählen

from Tkinter import *
import tkFileDialog,Image


class GUI:
    def __init__(self, parent):
        # main window
        self.Main = parent
        self.Main.title("Interpreter")
        self.Main.state('zoomed')
        # menu frame
        self.menuFrame = Frame(self.Main)
        self.menuFrame.pack(side=TOP,anchor=NW)

        # 1. File menu
        self.mb_File = Menubutton(self.menuFrame, text="File",
                                  relief=FLAT,activebackground='blue',
                                  activeforeground='white')
        self.mb_File.grid(column=0, row=0)
        self.mb_File.menu = Menu(self.mb_File, tearoff=0)
        self.mb_File["menu"] = self.mb_File.menu
        self.mb_File.menu.add_command(label="Load Image(s)...",command=self.loadImages)
        self.mb_File.menu.add_command(label="Open interpretation...")
        self.mb_File.menu.add_command(label="Save interpretation...")
        self.mb_File.menu.add_command(label="Exit",command=exit)
        #canvas
        self.canvas1 = Interpreter(self.Main)

    def loadImages(self):
        getNames = tkFileDialog.askopenfiles()
        names = []
        for name in getNames:
            names.append(name.name)
        names.sort()
        self.canvas1.displayImages(names)

    def exit(self):
        root.destroy()

class Interpreter:
    def __init__(self, parent):
        # scrolledCanvas
        self.ws = parent.winfo_screenwidth()
        self.hs = parent.winfo_screenheight()
        self.Pics = []
        self.Frame1 = LabelFrame(parent,text='Canvas')#,height=self.hs)
        self.Frame1.pack(fill=BOTH,expand=1,side=TOP)

        canv = Canvas(self.Frame1)
        canv.config(width=self.ws, height=self.hs)                
        canv.config(scrollregion=(0,0,self.ws, self.hs*10))                

        sbar = Scrollbar(self.Frame1)
        sbar.config(command=canv.yview)                   
        canv.config(yscrollcommand=sbar.set)              
        sbar.pack(side=RIGHT, fill=Y)                     
        canv.pack(side=LEFT, expand=YES, fill=BOTH)
        self.canvas = canv

    def displayImages(self,names):
        self.items = []
        i=0
        next = 0
        th = 0
        for imagename in names:
            next += th
            im = Image.open(imagename)
            imsize = list(im.size)
            w = imsize[0]
            h = imsize[1]
            f = 300.0/w
            temp = im.resize((f*w,f*h))
            th = list(temp.size)[1]
            temp.save('temp'+str(i)+'.gif')
            self.photo = PhotoImage(file='temp'+str(i)+'.gif')
            self.Pics.append(self.canvas.create_image(0, next, image=self.photo,anchor=W))
            i+=1
        self.canvas.config(scrollregion=(0,0,self.ws,next+th))
             
root = Tk()
myapp = GUI(root)
#root.mainloop()
BlackJack

@drewsilson: Du musst auf der Python-Seite Referenzen auf alle Bildobjekte behalten, sonst räumt der "garbage collector" die Bilddaten ab und Tk hat nichts mehr zum Anzeigen.

Wenn Du PIL verwendest, brauchst Du die Bilder nicht in temporären Dateien speichern. Es gibt `ImageTk.PhotoImage` dafür. Falls die Dateien doch gebraucht werden: Das `i` in der Schleife würde ich nicht "per Hand" hochzählen, sondern `enumerate()` verwenden.
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Danke! Ich probier das mal aus!
Auch danke fuer den enumerate tip! Hab mich bisher immer mit der
'per-hand-methode' durchgeschlagen... :oops:

Cheers
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

@BlackJack:
Sorry, ich dann doch noch mal:
tue mich irgendwie schwer damit meine Bild-referenzen zu behalten.

Was genau meinst du mit Bild-Referenzen?
Habe das mal so probiert, aber jetzt bekomme ich gar nichts mehr angezeigt...

Code: Alles auswählen

    def displayImages(self,names):
        i=0
        next = 0
        th = 0
        self.fotos = []
        for imagename in names:
            next += th
            im = Image.open(imagename)
            imsize = list(im.size)
            w = imsize[0]
            h = imsize[1]
            f = 300.0/w
            temp = im.resize((f*w,f*h))
            th = list(temp.size)[1]
            #temp.save('temp'+str(i)+'.gif')
            fotos.append(ImageTk.PhotoImage(temp))
            i+=1
        for foto in self.fotos:
            self.canvas.create_image(0, next, image=foto,anchor=W)
Danke!
BlackJack

@drewsilson: An sich schon nicht schlecht, aber überleg doch mal wo die Bilder jetzt *alle* platziert werden.
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Super! Habs!
Vielen Dank!
Antworten