Bild einfügen mit Tkinter

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

Donnerstag 16. April 2009, 20:02

derdon hat geschrieben:Und warum fangen deine Kommentare immer mit zwei ~ an?
Vermutlich verwendet er einen Editor, der per Shortcut diese Art von Kommentaren erzeugt. Bei SciTE sieht das so ähnlich aus. Damit lassen sich einzelne Zeilen/Blöcke sehr schnell (ent-)kommentieren.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Donnerstag 16. April 2009, 20:17

Das it ja ein ganz toller Editor :roll:
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Donnerstag 16. April 2009, 20:59

erstmal Danke für eure Pots

ich hab aber jetzt wieder das Bild als Label.

Ich würd gerne etwas auf das Bild schreiben, deswegen hätt ich das gerne als Frame.

@wuf:
nettes Bild im except-zweig, aber das ist nicht das Problem, test.gif lässt sich problemlos öffnen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Donnerstag 16. April 2009, 21:12

Pascal hat geschrieben:Ich würd gerne etwas auf das Bild schreiben, deswegen hätt ich das gerne als Frame.
Es wird Zeit, dass du mal in die Doku siehst: http://effbot.org/tkinterbook/tkinter-index.htm

Kurz gesagt: Ein "Bild als Frame" geht nicht. Braucht man auch nicht. Du kannst z.B. ein Label mit Bild versehen oder auch ein Canvas.
Willst du "in" das Bild schreiben, brauchst du die PIL, willst du etwas "über" das Bild schreiben, tut es ein Label auch, weil du Text und Bild übereinander platzieren kannst. Ist das nicht flexibel genug, nimmst du dafür ein Canvas.

In jedem Fall: Lies die Doku!
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Donnerstag 16. April 2009, 22:09

@Pascal
meinst du sowas in der Art

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf8 -*-

import Tkinter as tk
from PIL import Image
from ImageTk import PhotoImage

root = tk.Tk()
im = Image.open("test.gif")
foto = PhotoImage(im)
can = tk.Canvas(root,width=500,height=500)
can.grid()
can.create_image(0,0,anchor=tk.NW,image=foto)
can.create_text(242,20,text="Das ist ein Bild",fill="yellow")

root.mainloop()
Gruß...busfahrer
Alles wird gut ;-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Freitag 17. April 2009, 08:27

@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: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Freitag 17. April 2009, 08:46

...@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

Freitag 17. April 2009, 10:17

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: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Freitag 17. April 2009, 11:30

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

Samstag 18. April 2009, 10:55

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: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Samstag 18. April 2009, 11:08

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

Samstag 18. April 2009, 11:48

@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

Sonntag 19. April 2009, 11:32

@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

Sonntag 19. April 2009, 13:21

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: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Sonntag 19. April 2009, 14:29

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!
Antworten