Seite 1 von 2

Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 19. Dezember 2011, 16:30
von wilhelmO
Hallo , vielleicht kann mir geholfen werden ?

Durch folgendes Skript werden jeweils die letzten 12 Bilder aus einem Verzeichnis geladen und in einem Frame dargestellt. Dieser Vorgang
sollte jedoch zyklisch(automatisch) erfolgen, wenn wieder durch eine
Kamera ein neues Bild ins Verzeichnis gelangt. Im Frame sollten also die
jeweils 12 aktuellen Bilder angezeigt werden. Wenn ich mein Skript in eclipse
starte geschieht dies jedoch nur einmalig, ich finde keinen Lösungsansatz.

Code: Alles auswählen

from Tkinter import *
from PIL import Image,ImageTk
import sys,os
from time import *
root=Tk()
root.title('         TK 5 FormenScan')



b=[]
filenames=[]
highestno={}
highestfi={}
    
for filename in os.listdir("C:\\Python26\\AVT\\"):
    basename,extension = filename.split('.')
    filenames.append(filename)
    prefix,number=basename.split('AVT')
    if number>highestno.get(prefix,0):
        highestno[prefix]=number
        highestfi[prefix]=filename
        
prefixes=highestno.values()

bildno=prefixes[len(prefixes)-1]
bildno=int(bildno)  

    #print'filenames =',filenames
    #print'Type number=',type(number)
    #print 'BildNo=',bildno    


z=number
print z
print 'type Z=',type(z)

    
   
 
for n in range(12):
    
    image=Image.open("C:\Python26\AVT\AVT%s.png"%(z))
    image=image.resize((240,200),Image.ANTIALIAS)
    bild =ImageTk.PhotoImage(image)
    b.append(bild)
            
   
    print 'ZZ =',z
    z=int(z)
    if (100000>z>10000):
        z=z-1
        z='0000'+str(z)
                       
    elif (10000>z>1000):
        z=z-1
        z='00000'+str(z)
                        
    elif (1000>z>=101):
        z=z-1
        z='000000'+str(z)
        print 'z =',z
        
        
    elif (100>=z>=11):
        z=z-1
        print 'n',z
        z='0000000'+str(z)
        print 'all',z
               
    else :
        z=z-1
        z='00000000'+str(z)
        
        
    
bz=0
bno=len(filenames)
frame=Frame(root,width=600,height=800,borderwidth=4,bg='yellow')
frame.pack(side=TOP,fill=BOTH,expand=True)


for n in range(3):
    for i in range(4):
    
        label=Label(frame,image=b[bz])
        print 'Image =',image
        print 'BZ     =',bz
        bildlabel=Label(frame,text=filenames[((bno-1)-bz)])
        label.grid(row=n,column=i,padx=5,pady=7)   
        bildlabel.grid(row=n,column=i,sticky='N',padx=3,pady=5)
        bz=bz+1
if __name__ =='__main__':
    
        root.mainloop()
:K

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 19. Dezember 2011, 16:50
von Hyperion
Bitte setze Deinen Code in Python-Code-Tags! In Deinem ersten Thread hatte unsere Mutter Theresa des Code-Tags Hinzufügens BlackJack das dankenswerter Weise nachträglich für Dich übernommen. Im verlauf des Threads wurdest Du da leider nicht noch mal explizit darauf aufmerksam gemacht. Daher hier noch mal der explizite Hinweis darauf :-)

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 19. Dezember 2011, 18:39
von BlackJack
Und Mutter Theresa hat wieder zugeschlagen… :-D

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 19. Dezember 2011, 18:58
von Hyperion
BlackJack hat geschrieben:Und Mutter Theresa hat wieder zugeschlagen… :-D
Hier gibts ja keine Badges... sonst müssten wir einen für diese Tätigkeit erfinden :-D

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 19. Dezember 2011, 20:41
von BlackJack
@wilhelmO: Ein Lösungsansatz wäre in regelmässigen Abständen in dem Verzeichnis nach neuen Dateien zu schauen. Oder zumindest immer wieder die 12 aktuellsten Bilder anzuzeigen. Um so etwas regelmässig anzustossen kannst Du die `after()`-Methode verwenden die auf jedem `Tkinter`-Widget existiert.

Als Vorbedingung dafür muss der Code aber etwas ordentlicher und strukturierter werden und nicht einfach so alles auf Modulebene runtergeschrieben sein.

Am Anfang globale Datenstrukturen definieren und dann über das ganze, monolithische Programm verteilt darauf zugreifen ist 80er-Jahre BASIC-Stil.

Falls das so überhaupt funktioniert ist da übrigens auch ein wenig Zufall im Spiel, denn die Bedingung bei ``if number>highestno.get(prefix,0):`` könnte auch immer falsch sein und damit die Wörterbücher `highestno` und `highestfi` leer bleiben, mit all den Konsequenzen die daraus folgen. `number` ist hier nämlich eine Zeichenkette, und ob Zeichenketten mit Zahlen verglichen kleiner oder grösser sind, ist ein Implementierungsdetail. Es ist nur garantiert das alle Werte des einen Typs während eines Programmlaufs immer grösser, oder immer kleiner sind als alle Werte des anderen Typs. Mehr wird von der Sprache nicht zugesichert.

``prefixes[len(prefixes)-1]`` ist das selbe wie ``prefixes[-1]`` und semantisch in diesem fall sogar das selbe wie prefixes[0] — oder irgend ein anderer gültiger Index. Deshalb vermute ich auch hier einen Fehler im Programm. Willst Du wirklich irgendeinen zufälligen Wert aus dem Wörterbuch `highestno` haben!?

Es geht weiter mit ``z=number``: Warum!? Das ist der Teil nach 'AVT' des zuletzt verarbeiteten Dateinames — was auch wieder ein zufälliger Wert ist, denn `os.listdir()` macht keine Zusagen in welcher Reihenfolge die Dateinamen geliefert werden.

In der Schleife werden Bildnamen zusammen gesetzt wo ich mich frage was das Aufteilen des Dateinamens an 'AVT' weiter oben denn bewirken sollte, wenn doch davor anscheinend gar kein Prefix kommt!? Damit ist `highestno` unsinnig, denn es ist ein Wörterbuch mit nur einem Schlüssel/Wert-Paar.

Das was Du in der Schleife mit `z` anstellst ist ziemlich gruselig. Schau Dir mal bitte Zeichenkettenformatierung mittels ``%`` oder der `format()`-Methode an, was man da alles für die Formatierung von Zahlen zum Beispiel mit führenden 0en angeben kann.

Man sollte vermeiden Zeichenketten wie Pfade mehrfach literal in ein Programm zu schreiben. Wenn man zum Beispiel den Pfad einmal am Anfang an einen Namen bindet, braucht man ihn auch nur dort zu verändern.

`highestfi` und `filenames` wird anscheinend gar nicht verwendet?

Wenn ich das richtig sehe, dann sind die Dateinamen so beschaffen, dass sie alphabetisch sortiert in der richtigen zeitlichen Reihenfolge sind!? Dann ist der ganze Zirkus doch total überflüssig, denn dann würde zum Ermitteln der 12 letzten Bilder ``sorted(os.listdir(path), reverse=True)[:12]`` den ganzen komplizierten Code ersetzen können. Wobei mir gerade auffällt, dass Dein Code wohl auch nicht problemlos damit klar käme, wenn weniger als 12 Bilder vorhanden sind.

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 19. Dezember 2011, 20:55
von kaytec
Hallo wilhelmO !

Evt. könnte dir dieser Link helfen :
http://bytes.com/topic/python/answers/7 ... ation-date

Gruß Frank

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Dienstag 20. Dezember 2011, 17:22
von wilhelmO
Vielen Dank für eure Anworten. Habe bislang python nur im Zusammenhang
mit Bildverarbeitung als kleines Hilfsmittel eingesetzt. Klassen waren hierfür
nicht nötig.

Aufgabenstellung für mich ist: jeweils die aktuellen 12 Bilder in einem Frame
anzuzeigen. Die Bilder werden von der Kamera mit folgenden Namen gespeichert: AVT000000000.png bis AVT999999999.png.
Es sollte immer der gleiche Frame sein , der die 12 Bilder mit filename zeigt.

Unten mein bereinigter code. Die erste Ausführung enthielt in der Tat ziemlich
viel Käse. Und der Ausdruck 80er Jahre Basic-Stil ist schon zutreffend.

'sorted(os.listdir(path),reverse=True)[:12] 'kannte ich natürlich auch noch nicht. Dennoch liegen bei dem jetzigen script die Dateien geordnet vor , warum
auch immer.
:oops: Leider habe ich keine Ahnung, wie der unten stehende code wie in
IDLE oder eclipse farbig dargestellt werden kann. Vielleicht kann mir jemand
einen Hinweis geben :oops:

Code: Alles auswählen

from PIL import Image,ImageTk
import sys,os
from time import *
root=Tk()
root.title('         TK 5 FormenScan')



b=[]
picture=[]
filenames=[]

    
for filename in os.listdir("C:\\Python26\\AVT\\"):
    basename,extension = filename.split('.')
    filenames.append(filename)
    number=basename.split('AVT')
    b.append(number[1])
    #print 'number %s  ='%(b)
    
 
for n in range(12):
    
    image=Image.open("C:\Python26\AVT\AVT%s.png"%(b[(-12)+int(n)]))
    image=image.resize((240,200),Image.ANTIALIAS)
    bild =ImageTk.PhotoImage(image)
    picture.append(bild)
        
        
    
bz=0
bno=len(filenames)
frame=Frame(root,width=600,height=800,borderwidth=4,bg='yellow')
frame.pack(side=TOP,fill=BOTH,expand=True)


for n in range(3):
    for i in range(4):
    
        label=Label(frame,image=picture[bz])
        bildlabel=Label(frame,text=filenames[((bno-12)+bz)])
        label.grid(row=n,column=i,padx=5,pady=7)   
        bildlabel.grid(row=n,column=i,sticky='N',padx=3,pady=5)
        bz=bz+1
if __name__ =='__main__':
    
        root.mainloop()

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Dienstag 20. Dezember 2011, 17:25
von webspider
Jetzt bearbeite noch deinen Post und setz den Code eingerückt in die python-Tags :)

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Dienstag 20. Dezember 2011, 18:02
von BlackJack
@wilhelmO: Schau doch einfach mal in einen Deiner beiden Beiträge in diesem Thread in denen ich die Code-Tags gesetzt habe. Dann siehst Du wie man den Quelltext bunt und eingerückt darstellen lassen kann.

Die Dateinamen mögen bei Dir sortiert sein, aber das ist halt nicht garantiert dass das immer so ist. Wenn die Anforderung ist, dass die letzten 12 angezeigt werden, dann solltest Du das auch wirklich sicher stellen, und nicht hoffen dass das mit `os.listdir()` so schon irgend wie passt. Der Satz „The list is in arbitrary order.“ steht nicht ohne Grund in der Dokumentation zu der Funktion.

Was von ``sorted(os.listdir(path), reverse=True)[:12]`` kanntest Du denn nicht? Es kann ja eigentlich nur die `sorted()`-Funktion sein – die kennst Du doch aber *jetzt*. Das ist eine Funktion, die man nicht einmal importieren muss, die gehört zu den Grundwerkzeugen.

Das mit dem `b` (übrigens ein schlecht gewählter Name) ist immer noch unnötig umständlich. Statt die Namen, die Du schon hast zu verwenden, setzt Du sie noch einmal selbst neu zusammen. So wie es jetzt ausschaut muss man als Leser denken es werden mit `os.listdir()` andere Dateien aufgelisten als mit `Image.open()` geladen werden, weil es nur dann wirklich Sinn machen würde neue Namen für das öffnen zu erzeugen.

Wenn Du den gleichen Frame wiederverwenden willst, musst Du erstellen des Frames mit (Dummy-)Inhalt vom Laden und anzeigen der Bilder trennen. Denn den Frame musst Du nur einmal erstellen, Bilder laden und in den Labels anzeigen aber immer wieder.
Und die Label-Objekte musst Du Dir auch irgend wo merken, denn nur dann kannst Du sie später verändern, also neue Bilder und Beschriftungen darin anzeigen lassen.

Und *mindestens* das ermitteln, laden, und anzeigen der Bilder in den Labels im Frame muss in eine Funktion, denn `Widget.after()` braucht eine Funktion die es aufrufen kann.

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Mittwoch 21. Dezember 2011, 15:48
von wilhelmO
Hallo again. Habe mein script weiter verkürzt bzw. von allem Unnötigen befreit,
jedenfalls soweit ich das übersehen kann. Sicherlich gibt es noch eine Menge
Möglichkeiten alles noch kürzer und 'eleganter' zu erledigen.

Das script in der kürzeren Form zeigt mir meine 12 Bilder in einem Frame, aber
auch nicht mehr! Nichts mit einem zyklisch aktualisiertem Frame-Inhalt.

Also erstmal mein script verkürzt mit der Funktion wie oben beschrieben :

Code: Alles auswählen


from Tkinter import *
from PIL import Image,ImageTk
import sys,os

root=Tk()
root.title('         TK 5 FormenScan')
b=[]
picture=[]
filenames=[]

filenames=sorted(os.listdir("C:\\Python26\\AVT\\"),reverse=True)[:12]

for n in range(12):
    print filenames[-int(n)-1]
    image=Image.open("C:\Python26\AVT\%s"%(filenames[-int(n)-1]))
    image=image.resize((240,200),Image.ANTIALIAS)
    bild =ImageTk.PhotoImage(image)
    print bild
    picture.append(bild)
        
bz=0

frame=Frame(root,width=600,height=800,borderwidth=4,bg='yellow')
frame.pack(side=TOP,fill=BOTH,expand=True)


for n in range(3):
    for i in range(4):
    
        label=Label(frame,image=picture[bz])
        bildlabel=Label(frame,text=filenames[-(bz+1)])
        label.grid(row=n,column=i,padx=5,pady=7)   
        bildlabel.grid(row=n,column=i,sticky='N',padx=3,pady=5)
        bz=bz+1
if __name__ =='__main__':
    
        root.mainloop()  
Hier nun mein Versuch alles als Klasse zu behandeln:

Code: Alles auswählen


from Tkinter import *
from PIL import Image
import os



class bilder():
    
    
    
    def GetImages(self):
        print 'Bin in GetImages'
        self.filenames=[]
        self.filenames=sorted(os.listdir("C:\\Python26\\AVT\\"),reverse=True)[:12]

            
        

        
   
    def SammelImages(self):   
        from PIL import Image,ImageTk
        print 'Bin in ShowImages'
        weg="C:\\Python26\\AVT\\"
        
        for n in range(12):
            print self.filenames[-int(n)-1]
            image=Image.open("C:\Python26\AVT\%s"%(self.filenames[-int(n)-1]))
            image=image.resize((240,200),Image.ANTIALIAS)
            bild =ImageTk.PhotoImage(image)
            print bild
            self.picture.append(bild)
            

    def Rahmen(self):        
        self.root=Tk()
        self.root.title('         TK 5 FormenScan')
        print'Bin in doFrame'
        self.rahmen=Frame(self.root,width=600,height=800,borderwidth=4,bg='yellow')
        self.rahmen.pack(side=TOP,fill=BOTH,expand=True)
        
        
    def FillRahmen(self): 
        bz=0   
        self.images=self.picture
        for n in range(3):
            for i in range(4):
                                
                self.label=Label(self.rahmen,image=self.images[bz])
                bildlabel=Label(self.rahmen,text=self.filenames[int(n)-1])
                self.label.grid(row=n,column=i,padx=5,pady=7)   
                bildlabel.grid(row=n,column=i,sticky='N',padx=3,pady=5)
                bz=bz+1
                
    

if __name__ == '__main__':
    
    Mybilder=bilder()
    
    Mybilder.GetImages()
    Mybilder.SammelImages()   
    Mybilder.Rahmen() 
    Mybilder.FillRahmen()   
       
    Mybilder.root.mainloop()
Nach run in eclipse erhalte ich folgende, für mich nicht interpretierbare
Fehlermeldungen - anscheinend die ganze Hierarchie einmal durch


:oops: Hoffentlich erbarmt sich nochmal jemand , denn bevor ich dies
nicht gelöst habe ist an die von BlackJack erwähnte 'after()-Methode
und deren Schwierigkeiten noch in weiter Ferne

Hier die Fehlermeldungen:
Bin in GetImages
Bin in ShowImages
AVT000000215.PNG
Traceback (most recent call last):
File "D:\Eclipse_Python\TK5\src\test09.py", line 66, in <module>
Mybilder.SammelImages()
File "D:\Eclipse_Python\TK5\src\test09.py", line 32, in SammelImages
bild =ImageTk.PhotoImage(image)
File "C:\Python26\Lib\site-packages\PIL\ImageTk.py", line 113, in __init__
self.__photo = apply(Tkinter.PhotoImage, (), kw)
File "C:\Python26\lib\lib-tk\Tkinter.py", line 3285, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Python26\lib\lib-tk\Tkinter.py", line 3226, in __init__
raise RuntimeError, 'Too early to create image'
RuntimeError: Too early to create image
Exception AttributeError: "PhotoImage instance has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage instance at 0x00A48A08>> ignored
Vielen Dank im voraus für jede Hilfe !!

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Mittwoch 21. Dezember 2011, 16:15
von BlackJack
@wilhelmO: Das sind zwei Fehlermeldungen. Die erste sagt saus, dass es zu früh ist mit `ImageTk.PhotoImage()` zu erstellen und die zweite ist eine Folge davon. Zu dem Zeitpunkt muss Tk offenbar schon initialisiert sein.

Grundsätzlich sieht das mit der Klasse eher noch schlechter aus als vorher. Einfach eine Klasse definieren auf der dann jeglicher Code in Methoden gesteckt wird die ausschliesslich über Attribute auf dem Objekt kommunizieren ist im Grunde das gleiche wie alles auf Modulebene zu schreiben. Nur syntaktisch etwas umständlicher.

Du gehst da viel zu planlos dran und machst teilweise echt komische Sachen weil Dir anscheinend nicht klar ist was der Code macht und welche Datentypen mit welchen Werten Du jeweils vor Dir hast.

Ein Attribut an einen Wert binden gleich in der nächsten Zeile das Attribut an einen anderen Wert zu binden macht zum Beispiel keinen Sinn.

Oder das hier:

Code: Alles auswählen

        for n in range(12):
            print self.filenames[-int(n)-1]
Du hast Dir offensichtlich nicht klar gemacht oder angeschaut in welcher Reihenfolge die Namen in `self.filenames` vorliegen, wie viele das sind, welchen Typ `n` hat, und was der Index, den Du da berechnest tatsächlich an Werten aus der Liste holt. Oder soll die Anzeigereihenfolge *tatsächlich* *so* sein!?

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Donnerstag 22. Dezember 2011, 22:25
von kaytec
Hallo wilhelmO !

Code: Alles auswählen

import Tkinter as tk
from PIL import Image, ImageTk
import os

ROW = 3
COLUMN = 4
TITLE = "TK 5 FormenScan"
IMAGE_PATH = "/home/kaytec/Dokumente/images/"
RESIZE_IMAGE_WIDTH = 250
RESIZE_IMAGE_HEIGHT = 130


class Image_Viewer(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.images = self.load_images()
        for row, images in enumerate(self.images):
            for column, image in enumerate(images):
                tk.Label(self, image = image).grid(row = column, column = row)
   
    def load_images(self):
        images = sorted(os.listdir(IMAGE_PATH),reverse=True)
        sorted_images = list()
        for i in xrange(ROW):
            l = list()
            for i in xrange(COLUMN):
                l.append(ImageTk.PhotoImage(Image.open("%s%s" %(IMAGE_PATH, 
                    images.pop())).resize((RESIZE_IMAGE_WIDTH,
                    RESIZE_IMAGE_HEIGHT))))
            sorted_images.append(l)
        return sorted_images
    
if __name__ == '__main__':
    root = tk.Tk()
    image_viewer = Image_Viewer(root)
    image_viewer.pack()
    root.title(TITLE) 
    root.mainloop()
Gruß Frank

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Freitag 23. Dezember 2011, 09:22
von wilhelmO
guten Morgen kaytec - - herzlichen Dank --
Einem Anfänger wie mir ist mit einer aufgezeigten Lösung geholfen. Diese
kann ich 'nachvollziehen'.

Sobald ich den gesamten Ablauf verstanden habe werde ich versuchen für
die zyklische Aktualisierung des Frame - Inhalts eine Lösung zu finden.

Allen eine erholsame Weihnachtszeit

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Freitag 23. Dezember 2011, 09:37
von kaytec
Hallo wilhelmO !

Mein erster Urlaubstag ist heute und ich gehe den Tag ohne Xmas-Panik an. Ich habe auch schon mit einer zyklische Aktualisierung gespielt. Funktioniert soweit ganz gut, doch will ich dir nicht den Spaß nehmen.

Gruß Frank

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Freitag 23. Dezember 2011, 11:19
von wilhelmO
Nochmals vielen Dank kaytec ! Rückmeldung im Januar. :oops: Zeige dann
mal was ich zusammengewurstelt habe :)

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 9. Januar 2012, 11:43
von wilhelmO
Ein gesundes und entspanntes neues Jahr wünsche ich.

Bin selbst jedoch in einer endlos-loop mit meinem Versuch zyklisch die Bildanzeige zu erneuern.
Bestenfalls erreiche ich mit der after-methode ein Durchlaufen der def bilder,
load_images. Nachvollziehen kann ich dies durch die eingefügten print An-
weisungen. Aber ein Erneuern der Bildanzeige bekomme ich einfach nicht hin.
Egal wo ich es mit einer after - Anweisung versuche.

Unten mein "loop-programm" ohne Anzeige der Bilder.

Code: Alles auswählen


import Tkinter as tk
from PIL import Image, ImageTk
import os

ROW = 3
COLUMN = 4
TITLE = "TK 5 FormenScan"
IMAGE_PATH = "C:/Python26/AVT/"
RESIZE_IMAGE_WIDTH = 200
RESIZE_IMAGE_HEIGHT = 130


class Image_Viewer(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        print '1'
        self.bilder()
        
    def bilder(self):    
        self.images = self.load_images()
        print '2'
        for row, images in enumerate(self.images):
            print'5'
            for column, image in enumerate(images):
                print'6'
                tk.Label(self, image = image).grid(row = column, column = row)
        self.after(2000,self.bilder())     
        
        
    def load_images(self):
        images = sorted(os.listdir(IMAGE_PATH),reverse=True)
        print'3'
        sorted_images = list()
        print'4'
        for i in xrange(ROW):
            print'7'
            l = list()
            for i in xrange(COLUMN):
                print'8'
                l.append(ImageTk.PhotoImage(Image.open("%s%s" %(IMAGE_PATH, 
                    images.pop())).resize((RESIZE_IMAGE_WIDTH,
                    RESIZE_IMAGE_HEIGHT))))
            sorted_images.append(l)
        return sorted_images
      
    
if __name__ == '__main__':
    root = tk.Tk()
    root.title(TITLE) 
    image_viewer = Image_Viewer(root)
    image_viewer.pack()  
    root.mainloop()
    
Mir ist klar, das es wohl anscheinend nicht zu einem zyklischen image_viewer.pack() kommt. Jedoch ist mir als Anfänger auch keine Lösung
für dieses Problem gelungen.

Kann mir jemand weiterhelfen ?

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 9. Januar 2012, 16:19
von wuf
Hi wilhelmO

Hier etwas zum herumexperimentieren:

Code: Alles auswählen

import Tkinter as tk
from PIL import Image, ImageTk
import os

ROWS = 3
COLUMNS = 4
TITLE = "TK 5 FormenScan"
#~~ Testbilder befinden sich im Arbeitsverzeichnis
IMAGE_PATH = os.getcwd() #"C:/Python26/AVT/"
IMAGE_FORMAT_FILTER = ['.gif', '.png']
RESIZE_IMAGE_WIDTH = 48 #200
RESIZE_IMAGE_HEIGHT = 48 #130
DELAY = 100


class Image_Viewer(tk.Frame):
    
    def __init__(self, root):
        
        tk.Frame.__init__(self, root)
        self.pack()
          
        self.bilder()
       
    def bilder(self):
            
        self.images = self.load_images()
        
        for row, images in enumerate(self.images):
            for column, image in enumerate(images):
                self.label = tk.Label(self, image=image)
                self.label.grid(row=row, column=column)
                self.label.update_idletasks()
                self.label.after(DELAY, None)
                    
    def load_images(self):
        
        files = os.listdir(IMAGE_PATH)
        
        images = list()
        for file in files:
            for image_format in IMAGE_FORMAT_FILTER:
                if image_format in file:
                    images.append(file)

        images = sorted(images,reverse=True)
        
        sorted_images = list()
        for row in xrange(ROWS):
            row_list = list()
            for column in xrange(COLUMNS):
                try:
                    row_list.append(ImageTk.PhotoImage(Image.open(
                    images.pop()).resize(
                    (RESIZE_IMAGE_WIDTH, RESIZE_IMAGE_HEIGHT)
                    )))
                except IndexError:
                    break
            sorted_images.append(row_list)
            
        return sorted_images
     
if __name__ == '__main__':
    root = tk.Tk()
    root.update_idletasks()
    root.title(TITLE)
    image_viewer = Image_Viewer(root)
    #image_viewer.pack()  
    root.mainloop()
Gruß wuf :wink:

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Montag 9. Januar 2012, 18:55
von BlackJack
@wilhelmO: `after()` erwartet als zweites Argument die Funktion die aufgerufen werden soll. Du rufst da die Funktion selbst auf und übergibst deren Rückgabewert.

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Dienstag 10. Januar 2012, 16:37
von wilhelmO
Hallo BlackJack.

Ja, ok. Ich habe eine selbsverursachte endlos-loop. Daher sehe ich kein element von Tkinter
wie mein Frame mit den 12 labels auf denen ich dann die 12 Bilder "plazieren" kann.

Ich muss also mit after eine neu definierte Funktion ( methode ? ) aufrufen um den "alten"
Frame beizubehalten und "nur" jeweils neue Bilder darauf "ablegen".

Aber gerade das "gewußt wie" fehlt mir als Anfänger völlig.

Eine sogenannte slideshow habe ich auch schon gefunden und getestet. Aber ich will ja
keine ( wollen ? nein ! ) sogenannte slideshow, die solange läuft wie Bilder vorhanden sind.

Ich benötige einen Ablauf der mir jeweils die zwölf neuensten Bilder solange im Frame auf den
Labels anzeigt, bis zwölf neue Bilder vorhanden sind.



Kann mir jemand einen etwas konkreteren Lösungsweg zeigen ?


Das Programm von wuf habe ich ausprobiert. Es zeigt nur einen leeren Frame.
Ich kann auch nicht erkennen, wie dies hiermit geschehen könnte.
Die print - anweisungen benötige ich um den "programmablauf" nachzuvollziehen.

Re: Anzeige von 12 Bildern zyklisch erfolgen lassen

Verfasst: Dienstag 10. Januar 2012, 16:40
von Hyperion
Die Stelle, die BlackJack ansprach muss folglich so lauten:

Code: Alles auswählen

# Deine falsche Zeile
self.after(2000,self.bilder())
# so ist es richtig
self.after(2000, self.bilder)
Erkennst Du den Unterschied und ist Dir klar, wieso das so lauten muss?