Seite 1 von 1

Mehrere Bilder im Canvas?

Verfasst: Donnerstag 22. Oktober 2009, 15:59
von drewsilson
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()

Verfasst: Donnerstag 22. Oktober 2009, 16:18
von 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.

Verfasst: Donnerstag 22. Oktober 2009, 16:25
von drewsilson
Danke! Ich probier das mal aus!
Auch danke fuer den enumerate tip! Hab mich bisher immer mit der
'per-hand-methode' durchgeschlagen... :oops:

Cheers

Verfasst: Donnerstag 22. Oktober 2009, 16:46
von drewsilson
@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!

Verfasst: Donnerstag 22. Oktober 2009, 17:04
von BlackJack
@drewsilson: An sich schon nicht schlecht, aber überleg doch mal wo die Bilder jetzt *alle* platziert werden.

Verfasst: Donnerstag 22. Oktober 2009, 17:13
von drewsilson
Super! Habs!
Vielen Dank!