Seite 1 von 1
Tkinter erste animationen
Verfasst: Donnerstag 27. Dezember 2012, 16:43
von BerryBlue
Hallo Pythonforum,
Nach einigem rumprobieren mit Tkinter (python 2.7) schaff ich es einfach nicht, ein Bild einzufügen und dieses nach einer gewissen Zeit, ohne das man irgendeinen Knopf drückt das bild wechselt, also ein neues drübergezeichnet wir.
Wäre sehr dankbar über Lösungsvorshlage bzw. hilfen und Ideen.
MFG BerryBlue
PS: also sowas wie Animationen
Re: Tkinter erste animationen
Verfasst: Donnerstag 27. Dezember 2012, 16:47
von BlackJack
@BerryBlue: Man nimmt sich ein Widget welches ein Bild darstellen kann, zum Beispiel ein `Label` und benutzt die `after()`-Methode um das Bild durch ein anderes zu ersetzen.
Re: Tkinter erste animationen
Verfasst: Donnerstag 27. Dezember 2012, 16:52
von BerryBlue
Vielen dank für die schnelle Antwort, könnten Sie mir aber bitte ein Beispiel geben, da ich es iw. nicht verstehen.
MFG BerryBlue
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 00:01
von StefanLawl
Code: Alles auswählen
Bein.after(1000, treten)
Auto.after(20, bremsen)
Computer.after(340, ausschalten)
Label.after(500, ...

Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 11:35
von wuf
Hi BerryBlue
Hier eine konkrete Idee:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
try:
#~~ For Python 2.x
import Tkinter as tk
except ImportError:
#~~ For Python 3.x
import tkinter as tk
class App(object):
def __init__(self):
self.win = tk.Tk()
self.win.protocol("WM_DELETE_WINDOW", self.close)
def projector(self):
if self.picture_pointer == len(self.pictures):
self.picture_pointer = 0
self.picture_display.config(image=self.pictures[self.picture_pointer])
self.picture_pointer += 1
self.win.after(PAUSE, self.projector)
def run(self):
self.win.mainloop()
def close(self):
self.win.destroy()
APP_WIN_XPOS = 50
APP_WIN_YPOS = 50
SCRIPT_NAME = sys.argv[0]
IMAGES = ['Bild_01.gif', 'Bild_02.gif']
PAUSE = 500 # Milliseconds
app = App()
app.win.title(SCRIPT_NAME)
app.win.geometry('+{0}+{1}'.format(APP_WIN_XPOS, APP_WIN_YPOS))
app.pictures = [tk.PhotoImage(file=image) for image in IMAGES]
app.picture_pointer = 0
app.picture_display = tk.Label(app.win)
app.picture_display.pack()
app.projector()
app.run()
Gruß wuf

Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 11:57
von BlackJack
@wuf: Da ist jetzt aber einiges auf Modulebene was eigentlich in die `__init__()` gehört.
Und die Bahandlung von 'WM_DELETE_WINDOW' ist überflüssig solange man nicht noch etwas anderes dort machen möchte als nur das Fenster zu zerstören. Das passiert auch so.
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 12:38
von Sirius3
ein schönes Beispiel für itertools:
Code: Alles auswählen
from itertools import cycle
[...]
def projector(self):
self.picture_display.config(image=self.pictures.next())
self.win.after(PAUSE, self.projector)
[...]
app.pictures = cycle(tk.PhotoImage(file=image) for image in IMAGES)
Grüße
Sirius
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 13:38
von wuf
OK BlackJack
Habe das Skript nach deinen Anregungen angepasst und den Tipp von Sirius3 einfliessen lassen:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from itertools import cycle
try:
#~~ For Python 2.x
import Tkinter as tk
except ImportError:
#~~ For Python 3.x
import tkinter as tk
class App(object):
def __init__(self, images):
self.win = tk.Tk()
self.win.geometry('+{0}+{1}'.format(APP_WIN_XPOS, APP_WIN_YPOS))
self.win.protocol("WM_DELETE_WINDOW", self.close)
self.win.title(SCRIPT_NAME)
#self.pictures = [tk.PhotoImage(file=image) for image in images]
self.pictures = cycle(tk.PhotoImage(file=image) for image in images)
#self.picture_pointer = 0
self.picture_display = tk.Label(self.win)
self.picture_display.pack()
#def projector(self):
#if self.picture_pointer == len(self.pictures):
#self.picture_pointer = 0
#self.picture_display.config(image=self.pictures[self.picture_pointer])
#self.picture_pointer += 1
#self.win.after(PAUSE, self.projector)
def projector(self):
self.picture_display.config(image=self.pictures.next())
self.win.after(PAUSE, self.projector)
def run(self):
self.win.mainloop()
def close(self):
print('Good Bye')
self.win.destroy()
APP_WIN_XPOS = 50
APP_WIN_YPOS = 50
SCRIPT_NAME = sys.argv[0]
IMAGES = ['Bild_01.gif', 'Bild_02.gif']
PAUSE = 500 # Milliseconds
app = App(IMAGES)
app.projector()
app.close_button = tk.Button(app.win, text='Schliessen', command=app.close)
app.close_button.pack()
app.run()
BlackJack hat geschrieben:Und die Bahandlung von 'WM_DELETE_WINDOW' ist überflüssig solange man nicht noch etwas anderes dort machen möchte als nur das Fenster zu zerstören. Das passiert auch so.
Das nehme ich bei meinen Skripts als Standard rein im Falle man doch auf die Idee kommt vor der Vorhangschliessung des Auftritts noch etwas auszuführen.
@Sirius3: Danke für deinen Tipp mit der Methode 'cycle' des Moduls 'itertools'. Funktioniert unter Python 2.6 bestens aber unter Python 3.x wird folgende Exception geworfen:
Traceback (most recent call last):
File "label_dia_images_02.py", line 58, in <module>
app.projector()
File "label_dia_images_02.py", line 40, in projector
self.picture_display.config(image=self.pictures.next())
AttributeError: 'itertools.cycle' object has no attribute 'next'
Gruß wuf

Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 13:50
von BlackJack
@wuf: Iteratoren haben in Python 3 keine `next()`-Methode mehr, dafür gibt es eine `next()`-Funktion. Die gibt es schon ab Python 2.6, also wenn Du keine ältere Version unterstützen möchtest, kann man die entsprechende Zeile einfach so ändern:
Code: Alles auswählen
self.picture_display.config(image=next(self.pictures))
Edit: Da der OP Python 2.7 einsetzt ist das aber eigentlich auch kein Problem von Sirius3 sondern von Deiner zusätzlichen Anforderung, dass es auch mit Python 3 laufen soll.
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 13:50
von yipyip
@wuf:
(Python 3.3)
Code: Alles auswählen
>>> from itertools import cycle
>>> seq = range(3)
>>> cs = cycle(seq)
>>> cs.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'itertools.cycle' object has no attribute 'next'
>>> next(cs)
0
>>> next(cs)
1
>>> next(cs)
2
>>> next(cs)
0
>>> cs.__next__()
1
>>> cs.__next__()
2
...
Siehe auch:
http://python3porting.com/differences.html#next
yipyip
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 16:23
von wuf
Hi BlackJack & yipyip
Danke für eure hilfreichen Antworten und Links. Habe das Skript somit auf den neuesten Stand für Py2.6 plus und Py3.x gebracht:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from itertools import cycle
try:
#~~ For Python 2.x
import Tkinter as tk
except ImportError:
#~~ For Python 3.x
import tkinter as tk
class App(object):
def __init__(self, images):
self.win = tk.Tk()
self.win.geometry('+{0}+{1}'.format(APP_WIN_XPOS, APP_WIN_YPOS))
self.win.protocol("WM_DELETE_WINDOW", self.close)
self.win.title(SCRIPT_NAME)
self.pictures = cycle(tk.PhotoImage(file=image) for image in images)
self.picture_display = tk.Label(self.win)
self.picture_display.pack()
def projector(self):
self.picture_display.config(image=next(self.pictures))
self.win.after(PAUSE, self.projector)
def run(self):
self.win.mainloop()
def close(self):
print('Good Bye')
self.win.destroy()
APP_WIN_XPOS = 50
APP_WIN_YPOS = 50
SCRIPT_NAME = sys.argv[0]
IMAGES = ['Bild_01.gif', 'Bild_02.gif']
PAUSE = 500 # Milliseconds
app = App(IMAGES)
app.projector()
app.close_button = tk.Button(app.win, text='Schliessen', command=app.close)
app.close_button.pack()
app.run()
BlackJack hat geschrieben:Edit: Da der OP Python 2.7 einsetzt ist das aber eigentlich auch kein Problem von Sirius3 sondern von Deiner zusätzlichen Anforderung, dass es auch mit Python 3 laufen soll.
Ist jetzt natürlich klar. Sorry an Sirius3 sollte er mich hier missverstanden haben.
Gruß wuf
Edit: Habe die Fallunterscheidung von 'next' für Python2.x & 3.x korrigiert.
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 18:27
von yipyip
@wuf:
Du brauchst doch gar keine Fallunterscheidung mit try...except zu machen. Die 'next(<iterator>)' Funktion gibts doch fuer Python 2.6+ sowie Python 3 (wie BlackJack schon sagte).
Jetzt laeufts auch mit Python 2.5- !?
yipyip
Re: Tkinter erste animationen
Verfasst: Freitag 28. Dezember 2012, 20:55
von wuf
Danke yipyip
Da habe ich BlackJack falsch verstanden. Setzte das Modul 'itertools' bis jetzt noch nie ein. Das vereinfacht das Skript natürlich noch mehr.
Gruß wuf
