Nach Veränderung des Labels wird trotzdem das alte angezeigt

Fragen zu Tkinter.
Antworten
Krabman318
User
Beiträge: 21
Registriert: Sonntag 14. August 2011, 14:36

Wie gesagt, ein Label wird verändert und platziert(bildlabel = Label(image=bild)[ja, bild ist definiert!] bildlabel.place(x = 50, y = 0), allerdings ist trotzdem nur das Label in seiner vorherigen Form zu sehen, eine Fehlermeldung erscheint nicht, es passiert gar nichts.
Jetzt würde ich natürlich gerne wissen, wo der Fehler liegt.
Mit dem Programm, das ich zusammen mit einem Freund schreibe, soll man in einem (sehr) kleinen Teil(eine Straße oder so) von Heidelberg vor und zurück gehen und sich drehen können, mehr oder weniger wie in Google Street View.
Vor oder zurück gehen soll man nur können, wenn man nicht gedreht ist.

Code: Alles auswählen

testvar = dictionary_start[bildliste[bildposition]]
    if drehposition == 0:
        bild = PhotoImage(file=bildliste[bildposition])
    elif testvar == 1:
        bild = PhotoImage(file=dictionary1[drehposition])
    elif testvar == 2:
        bild = PhotoImage(file=dictionary2[drehposition])
    elif testvar == 3:
        bild = PhotoImage(file=dictionary3[drehposition])
    elif testvar == 4:
        bild = PhotoImage(file=dictionary4[drehposition])
    elif testvar == 5:
        bild = PhotoImage(file=dictionary5[drehposition])
    elif testvar == 6:
        bild = PhotoImage(file=dictionary6[drehposition])
    elif testvar == 7:
        bild = PhotoImage(file=dictionary7[drehposition])
    elif testvar == 8:
        bild = PhotoImage(file=dictionary8[drehposition])
    elif testvar == 9:
        bild = PhotoImage(file=dictionary9[drehposition])
    elif testvar == 10:
        bild = PhotoImage(file=dictionary10[drehposition])
    bildlabel = Label(image=bild)
    bildlabel.place(x = 50, y = 0)#seltsamerweise kommt kein neues Bild
   
Ganzer Quelltext:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich habe zwar keine Lösung für das eigentliche Problem, aber bei dem gezeigten Schnipsel ist einiges an Verbesserungspotenzial zu sehen ;-)

Code: Alles auswählen

    if drehposition == 0:
        bild = PhotoImage(file=bildliste[bildposition])
    elif testvar == 1:
        bild = PhotoImage(file=dictionary1[drehposition])
    elif testvar == 2:
        bild = PhotoImage(file=dictionary2[drehposition])
    ... usw.
Ihr nummeriert eine Variable durch - das ist fast immer ein Zeichen dafür, dass man eine Liste o.ä. verwenden sollte. Anstelle der Nummerierung könntet Ihr die einzelnen Dicts in eine Liste packen und dann über den Index darauf zugreifen:

Code: Alles auswählen

# voher:
filenames = [
    # ehemaliges Dictionary1
    {
    },
    # ehemaliges Dictionary2
    {
    }, # usw.
]
# und dann
    if drehposition == 0:
        bild = PhotoImage(file=bildliste[bildposition])
    elif testvar:
        bild = PhotoImage(file=filenames[testvar][drehposition])
Einzig der Wert von testvar müsste so bei 0 starten und nicht bei 1, wie oben gezeigt. Evtl. kann man das leicht ändern? Alternativ eben "-1" in den Indexzugriff schreiben.

Man kann so vor allem einfach eine beliebige Anzahl an Dictionaries verwenden, ohne den Code verändern zu müssen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Krabman318
User
Beiträge: 21
Registriert: Sonntag 14. August 2011, 14:36

Vielen Dank für die gute Idee-
Ich werde sie gleich umsetzen.
EDIT: Seltsamerweise hat sich mein Problem gerade selbst gelöst. :K
Nachdem ich diese Änderung vorgenommen hatte, wurde plötzlich das richtige Bild im Label angezeigt:D
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Noch etwas: Den Namen ``file`` sollte man nicht verwenden, da es sich dabei um ein Built-in handelt. Vermutlich meintet ihr ja ``filename`` ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Krabman318
User
Beiträge: 21
Registriert: Sonntag 14. August 2011, 14:36

Wie meinst du das?
Mit "filename" wird bild doch gar keine Datei zugewiesen, da der Dateiname nicht als gültiger Parameter(bzw. die Option "file") übergeben wird.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Krabman318 hat geschrieben:Wie meinst du das?
Mit "filename" wird bild doch gar keine Datei zugewiesen, da der Dateiname nicht als gültiger Parameter(bzw. die Option "file") übergeben wird.
Arg... sorry, mein Fehler! Hatte übersehen, dass es sich um ein positional argument handelt. Alles ok :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

Es wär doch auch eine Idee

Code: Alles auswählen

    bildlabel = Label(image=bild)
    bildlabel.place(x = 50, y = 0)
durch eine Funktion z. B.

Code: Alles auswählen

def bildupdaten():
    global bild, bildlabel
    bildlabel = Label(image=bild)
    bildlabel.place(x = 50, y = 0)
zu ersetzen.
Fail quickly and try except!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nothing but Python hat geschrieben:Es wär doch auch eine Idee
...
zu ersetzen.
Da Du ein global in Deinem Code hast, ist das keine gute Idee ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

Naja, aber wie sonst?

Code: Alles auswählen

    b1 = Button(bildfenster, text = "Nach Vorne!", command = nach_vorne(bildposition, bild, bildlabel, drehposition))
funktioniert leider nicht.
Fail quickly and try except!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nothing but Python hat geschrieben:Naja, aber wie sonst?
Anders ;-) Mal im Ernst: ``global`` ist eigentlich immer unnötig. In Deinem Falle kann man das doch einfachst per Parameterübergabe oder -rückgabe lösen!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

Sicher, dass man, wenn die Funktion per Button aufgerufen wird, ihr Parameter übergeben kann :?:
Fail quickly and try except!
deets

Natuerlich, indem man sie vorher mittels "functools.partial" bindet. Natuerlich musst du dann schon etwas haben, auf dem sich die Werte sinnvoll setzen lassen - zB ein Applikations-Objekt oder sowas.
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

Wieso steht in der Funktion nach_links eigentlich:

Code: Alles auswählen

    if testvar == "1":
        bild = PhotoImage(file=dictionary1[drehposition])
    elif testvar:
        bild = PhotoImage(file=dictionaryliste[testvar][drehposition])
?
Ein einfaches

Code: Alles auswählen

        bild = PhotoImage(file=dictionaryliste[testvar][drehposition])
genügt doch!
Ausserdem wird doch gar keine dictionary1 deklariert.
Warum funktioniert das Programm trotzdem?
:?:
Fail quickly and try except!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nothing but Python hat geschrieben:Wieso steht in der Funktion nach_links eigentlich:

Code: Alles auswählen

    if testvar == "1":
        bild = PhotoImage(file=dictionary1[drehposition])
    elif testvar:
        bild = PhotoImage(file=dictionaryliste[testvar][drehposition])
?
Ein einfaches

Code: Alles auswählen

        bild = PhotoImage(file=dictionaryliste[testvar][drehposition])
genügt doch!
Das schrieb ich bereits ganz oben ;-)
Nothing but Python hat geschrieben: Ausserdem wird doch gar keine dictionary1 deklariert.
Warum funktioniert das Programm trotzdem?
:?:
Weil es auf Modulbene definiert wird:

Code: Alles auswählen

In [4]: def foo():
   ...:     print bar
   ...:     
   ...:     

In [5]: bar = 42

In [6]: foo()
42
Man beachte dabei aber:

Code: Alles auswählen

In [7]: def foo(bar):
   ...:     print bar
   ...:     
   ...:     

In [8]: foo(12)
12
Hier wird im Namensraum der Funktion der Name bar neu gebunden - daher wird hier nicht mehr auf den Namen der Modulebene (da war ja 42 an bar gebunden) zurückgegriffen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

Es wäre doch auch besser wenn du statt

Code: Alles auswählen

From tkinter import*

Code: Alles auswählen

import tkinter as Tk
Und dann halt z.B.

Code: Alles auswählen

bildfenster = Tk.Tk()
schreibst.
Oder :?:
Fail quickly and try except!
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

Lieber Krabman318,

Es wäre doch auch eine gute Idee, wie deets schon schrieb, eine Klasse einzuführen:

Code: Alles auswählen

class klasse([die ganzen dictionaries], bildfenster = Tk()):
    self.
Und so weiter.

EDIT:Ich war zu faul die ganze Klasse hinzuschreiben. :lol:
Fail quickly and try except!
Krabman318
User
Beiträge: 21
Registriert: Sonntag 14. August 2011, 14:36

@Nothing but Python:
Das halte ich für eine gute Idee, besonders weil ich gestern damit angefangen und du und ich es dann zusammen gemacht haben! :roll:
Benutzeravatar
Nothing but Python
User
Beiträge: 12
Registriert: Montag 15. August 2011, 18:24

:lol:
Fail quickly and try except!
Antworten