Bild einfügen mit Tkinter

Fragen zu Tkinter.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@busfahrer: Um eine Grafikdatei in einem Tkinter-Widget anzuzeigen, brauchst du das PIL-Modul nicht (in jedem Fall). So lange du dich auf gif (und einige wenige andere, weniger gebräuchliche Formate) beschränkst, braucht du die PIL nicht. Aber mit png oder jpeg kommt Tkinter alleine - ohne PIL - nicht zurecht.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

...@derdon
derdon hat geschrieben:Nach 505 Posts zeigst du einem Anfänger ein reines except (das *unter anderen* NameError, KeyboardInterrupt und SyntaxError beinhaltet) als Beispiel?
Wie würdest du den try: except: Zweig in meinem Beispiel gestalten? Könntest du bitte deine Variante hier in Code-Form präsentieren. Dann würden auch wir Anfänger etwas davon profitieren.

Ich verwende nicht einen Editor welcher die ~~ automatisch wirft. Das ist mein persönlicher Kommentarschmuck. Ich hoffe er irritiert dich nicht zu stark.

P.S. Die Nummer 505 könnte eine Glückszahl sein (Millionengewinn :lol: )

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

wuf hat geschrieben:Wie würdest du den try: except: Zweig in meinem Beispiel gestalten? Könntest du bitte deine Variante hier in Code-Form präsentieren. Dann würden auch wir Anfänger etwas davon profitieren.
Ganz Unrecht hat er nicht mit seinem Hinweis, auch wenn ich es in diesem Fall - nur eine Zeile im try-Block - für nicht so tragisch halte.
Grundsätzlich sollte man ein nacktes "except" schon vermeiden bzw. sich wieder abgewöhnen.

Im konkreten Fall müsste der Code lauten:

Code: Alles auswählen

try:
    my_photo = tk.PhotoImage(file="test.gif")
except tk.TclError:
    my_photo = tk.PhotoImage(data=MY_IMAGE)
Einen IO-Error wie beim missglückten Öffnen einer Datei via open() gibt es an dieser Stelle (leider) nicht, so dass man durch den TclError auch Fehler abfängt, die nicht mit der Nicht-Existenz der Datei zu tun haben (etwa wenn man fil="..." statt file="..." schreibt).

Deine Variante mit dem bloßen except würde z.B. auch dann das Ersatzbild anzeigen, wenn man z.B. statt "tk.PhotoImage" dummerweise "tk.Photoimage" schreibt, auch wenn die Datei ordnungsgemäß vorhanden ist. Das erschwert einem dann unnötig die Fehlersuche ... :wink:
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo numerix

Danke für deine klärende Antwort. Wenn ich mein Beispiel ohne try-except-Zweig nur mit:

Code: Alles auswählen

my_photo = tk.PhotoImage(file="test.gif")
ausführe wird folgende Exception ausgelöst:

Code: Alles auswählen

Traceback (most recent call last):
  File "image_insert_01_02.py", line 58, in <module>
    my_photo = tk.PhotoImage(file="test.gif")
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 3270, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 3226, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't open "test.gif": no such file or directory
Meine Schwierigkeit war das richtige Exception-Schlüsselwort herauszufinden. Um die Exception abzufangen probierte ich es mit '_tkinter.TclError' was natürlich nicht funktionierte. Die Lösung war dein Schlüsselwort 'tk.TclError'!

@Pascal: Hier ist mein bereinigtes Beispiel:
http://paste.pocoo.org/show/112919/

@numerix: Besten Dank für deinen lehrreichen Tipp:

@derdon: Somit hat sich das unsaubere erledigt. Danke für dein Hinweis.

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Da ich mir häufig auch nicht sicher bin, welche Exceptions ausgelöst werden, verwende ich gern so etwas:

Code: Alles auswählen

try:
    meine_funktion()
except Exception, error:
    print 'Fehler beim Ausführen von meine_funktion: %s' % error
MfG
HWK
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo HWK

Danke für den brauchbaren Tipp.

Gruss wuf :wink:
Take it easy Mates!
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

@HWK: Das sollte man aber nur machen, wenn man auch wirklich alle Exceptions außer SystemExit, KeyboardInterrupt und GeneratorExit abfangen möchte. Und nicht, wenn man sich nicht sicher ist, welche Exception für den Traceback verantwortlich ist.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

@derdon: Wie würdest Du denn z.B. Exceptions abfangen, wenn Du bei fremden Funktionen nicht weißt, wieviele und welche auftreten können, Du Dir aber ziemlich sicher bist, dass sie den weiteren Programmablauf nicht stören? Die Idee ist doch, dass Du (fast) alle Exceptions abfängst und dann überprüfen kannst, welche es waren. Mit den damit gewonnenen Infos kann das Exception-Handling dann angepasst werden, indem man z.B. nur noch bestimmte Exceptions abfängt oder bestimmte Exceptions im Handler anders behandelt.
MfG
HWK
lunar

HWK hat geschrieben:@derdon: Wie würdest Du denn z.B. Exceptions abfangen, wenn Du bei fremden Funktionen nicht weißt, wieviele und welche auftreten können, Du Dir aber ziemlich sicher bist, dass sie den weiteren Programmablauf nicht stören?
Das widerspricht sich. Du kannst dir nur dann wirklich sicher sein, dass der weitere Programmablauf nicht gestört wird, wenn du weißt, welche Ausnahmen warum ausgelöst werden. In diesem Fall aber kannst du auch die exakten Typen abfangen.

Allgemein alle Ausnahmen abzufangen, und anschließend eine nichtssagende Fehlermeldung ohne Traceback auszugeben, erschwert das Debugging über die Maßen, wenn dann doch mal eine Ausnahme auftritt, die den Programmablauf empfindlich stört.

Außerdem würde ich persönlich bei einer Fehlermeldung nicht davon sprechen, dass der Programmablauf nicht gestört wurde. Davon kann man nur sprechen, wenn man gutem Gewissen "pass" in den except-Block schreiben kann, oder die Ausnahme erwartet wurde und der Kontrollfluss anderweitig fortgesetzt werden kann.

Fazit: Man fängt niemals blind alle Ausnahmen ab, sei es mit einem bloßen "except" oder mit "except Exception", wenn man nicht wenigstens den Traceback irgendwo loggt!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo numerix

Habe ein Frage. Wie bist du auf den Exception-Namen tk.TclError gestossen?
Gehe ich richtig in der Annahme du hast ihn beim durchsuchen des Tkinter.py Skriptes gefunden?

Für Python2.5 wäre dies auf Zeile 40
(Version = __version__ = "$Revision: 50704 $")

Für Python2.6 wäre dies auf Zeile 41
(Version = __version__ = "$Revision: 67083 $")

Da steht folgendes:

Code: Alles auswählen

TclError = _tkinter.TclError
Da Tkinter als tk importiert wird entsteht somit:

Code: Alles auswählen

tk.TclError
entspricht in diesem Falle aber auch:

Code: Alles auswählen

tk._tkinter.TclError
So kann das Exception Abfang Codefragment in meinem Beispiel wie folgt aussehen:
Variante-1 (schon bekannt):

Code: Alles auswählen

try:
    #~~ Versucht die Bilddaten aus der Datei 'test.gif' einzulesen
    my_photo = tk.PhotoImage(file="test.gif")
except tk.TclError , err:
    #~~ Die Datei wurde nicht gefunden! Verwende die Konstante MY_IMAGE
    #   fuer die Bilddaten
    print "Tcl-Error", err
    my_photo = tk.PhotoImage(data=MY_IMAGE)
Variante-2 (Exception-Name aus dem Traceback http://www.python-forum.de/post-132364.html#132364 abgeleitet):

Code: Alles auswählen

try:
    #~~ Versucht die Bilddaten aus der Datei 'test.gif' einzulesen
    my_photo = tk.PhotoImage(file="test.gif")
except tk._tkinter.TclError, err:
    #~~ Die Datei wurde nicht gefunden! Verwende die Konstante MY_IMAGE
    #   fuer die Bilddaten
    print "Tcl-Error", err
    my_photo = tk.PhotoImage(data=MY_IMAGE)
Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

wuf hat geschrieben:Hallo numerix
Habe ein Frage. Wie bist du auf den Exception-Namen tk.TclError gestossen?
Exception ausgelöst, Traceback angesehen, drüber nachgedacht, ausprobiert, fertig. :wink:
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

.... Super Genial!

Gruss wuf :wink:
Take it easy Mates!
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

auch wenn dieser Theard nicht ganz aktuell ist...

in der Zeit bin ich etwas weiter gekommen was python angeht :)

aber jetzt dazu noch eine Frage:

Code: Alles auswählen

import Tkinter as tk


win = tk.Tk()  
win.minsize(500,500) 
photo = tk.PhotoImage(file=test)

## Hier sieht man das ganze Bild
##label = Label(image=photo) 
##label.image = photo 
##label.pack()


canvas=tk.Canvas(win, width=1400, height= 1000, bg='white')
canvas.pack()


## hier jedoch erscheint nur ein Teil des Bildes, woran liegt das??
canvas.create_image(0,0,image=photo)
Danke für eure bisherige Hilfe und auch schonmal Danke für die (hoffentlich) noch kommenden Antworten ;) :idea:
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Versuchs' mal mit

Code: Alles auswählen

canvas.create_image(0,0,image=photo, anchor=tk.NW)
Der Defaultwert für 'anchor' ist 'CENTER',
d.h. Deine Koordinaten (0, 0) bestimmen den
*Mittelpunkt* eines Bildes, daher siehst Du bis jetzt wohl nur
das rechte, untere Viertel.

Für all diese Optionen immer in den Effbot gucken.
http://effbot.org/tkinterbook/

:wink:
yipyip
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

hey super, vielen Dank!!
Antworten