Text in Label aktualisieren die Xte

Fragen zu Tkinter.
Antworten
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

Hallo zusammen!

Ich weiss, das Thema wurd nun schon oft hier durchgekaut, aber irgendwie finde ich einfach keine richtige Lösung zu meinem Problem.

Folgendes:
In meiner GUI gibt es mehrere Frames die allesamt Instanzen von bestimmten Klassen sind. In den init-Methoden der Klassen werden verschiedene Labels angelegt, die Daten mittels einer uebergebenen Methode aus einer Datenklasse lesen und anzeigen.
Durch Benutzereingaben in einem TopLevel-Window können die Daten der Datenklasse geändert werden. Wird das TopLevel anschließend geschlossen, sollen die dargestellten Daten in den Labels der Frames aktualisiert werden.

Bsp: (o.G.)

Code: Alles auswählen

import Tkinter

class Frameklasse(object):

  def __init__(self, parent, dateninst):
    self.parent = parent
    self.dateninst = dateninst

    self.textlabel = Tkinter.Label(self.parent.root, text=' %s ' % self.dateninst.getData())
    return

========================
class datenklasse(object)
  
  def __init__(self):
    self.anzeigestring = 'blablablub'
    return

  def getData(self):
    return self.anzeigestring

  def setData(self, newData):
    self.anzeigestring = newData
    return
========================

root = Tkinter.Tk()

dateninstanz = datenklasse()
frameinstanz = Frameklasse(root, dateninstanz)
Wie schaffe ich es nun, dass sich die angezeigten Daten im Label nach dem Schließen des TopLevels aktualisieren?
Ich weiss, ich könnte der Frameklasse eine Methode "update", oder so implementieren, die die Labels dann rekonfiguriert
z.B.

Code: Alles auswählen

  def update(self, dateninst)
    self.dateninst = dateninst
    self.textlabel.config( text=' %s ' % self.dateninst.getData()
    return
und diese dann jedes Mal aufrufen. Aber da ich sehr viele Frames und Labels habe, finde ich das nicht sehr praktisch.
Nach dem Schließen des Toplevels ein Update der Frames bzw. des roots mit

Code: Alles auswählen

frameinstanz.update()
zu erzwingen bringt leider auch nichts.
Muss ich nun doch eine zentrale UpdateMethode schreiben die mir jedes Mal alle meine Frames und Labels durchackert oder gibts da noch eine bessere Lösung? :roll:

Gruß,
Simon

PS: Schönen Feiertag, wenns soweit ist!
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

Ich deute euer Schweigen mal so, dass ich wohl doch eine UpdateMethode in jeder Klasse implementieren und die dann jedes Mal aufrufen muss? :?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

dahaze hat geschrieben:Ich deute euer Schweigen mal so, dass ich wohl doch eine UpdateMethode in jeder Klasse implementieren und die dann jedes Mal aufrufen muss? :?
Einen gänzlich anderen Weg sehe ich in der Tat nicht.

Wenn klar ist, dass sich der Inhalte eines Labels irgendwann ändern kann, dann ist es aber irgendwie auch vernünftig, wenn man dafür von vornherein eine entsprechende update()-Methode vorsieht und nicht nur eine einmalige Befüllung bei der Instanzbildung.

Mit einer geeigneten übergeordneten Datenstruktur (Dictionary oder Liste) kann man alle Labels sammeln und bei einem Update der Daten einfach diese Liste/Dictionary durchlaufen.
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

Hallo Numerix,

danke für die Antwort.
Da ich ein Neuling in der Python Programmierung bin, dachte ich, ich frag einfach mal. :wink:
Hätt ja sein können, dass es in Tkinter schon ne Methode gibt, die mir das abnimmt oder ich generell nur einen Denkfehler drin hab.
Dann komme ich wohl nicht drum herum die Geschichte selber zu coden.

Gruß ausm Schwabenland!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo dahaze

Habe dein Code-Snippet durch kleine Änderungen und Ergänzungen lauffähig gemacht:

Code: Alles auswählen

import Tkinter as tk

class Frameklasse(object):

  def __init__(self, parent, dateninst):
    self.parent = parent
    self.dateninst = dateninst

    self.textlabel = tk.Tkinter.Label(self.parent,
        text=' %s ' % self.dateninst.getData())
    self.textlabel.pack()

# ========================
class datenklasse(object):
 
  def __init__(self):
    self.anzeigestring = 'blablablub'

  def getData(self):
    return self.anzeigestring

  def setData(self, newData):
    self.anzeigestring = newData

# ========================

root = Tkinter.Tk()

dateninstanz = datenklasse()
frameinstanz = Frameklasse(root, dateninstanz)

root.mainloop()
So wie ich dich verstehe gibt es bei deiner Anwendung ein Hauptfenster (ist nicht einTop-Level Widget sondern das 'root'-Fenster) auf dem sich Labels eingepackt in Frame-Widgets befinden. Die Labels zeigen die Daten aus deiner Daten-Klasse an. Die in den Labels angezeigten Daten können nun über ein Top-Level-Fenster (in Tkinter als Toplevel-Widget bezeichnet) das als Dialogfenster dient und auf dem sich Eingabe-Widgets befinden mit denen die Label-Inhalte via die Daten-Klasse auf dem Hauptfenster verändert werden können. Die Änderung der Daten erfolgt aber erst beim schliessen des Top-Level-Widgets (Dialog mit den Eingabe-Widgets) nicht nach dem beenden einer Eingabe in ein Eingabe-Widget? Sollte eigentlich kein Problem sein.

Eine Möglichkeit für das aktualisieren hat dir numerix schon vorgeschlagen Das codieren musst du aber schon selber erledigen. Deine Versuche kannst du hier präsentieren. Es gibt dann sicher genug Leute die dir dabei helfen werden

Gruss wuf :wink:
Take it easy Mates!
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

@wuf
ausgehend von dieser Zeile

Code: Alles auswählen

import Tkinter as tk
müsste es doch eigentlich so heissen

Code: Alles auswählen

self.textlabel = tk.Label(self.parent,
        text=' %s ' % self.dateninst.getData())
und

Code: Alles auswählen

root = tk.Tk()
oder?

Gruß...busfahrer
Alles wird gut ;-)
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo busfahrer

Du hast natürlich 100% recht. Wie du siehst kann auch wuf eine Pfuscharbeit abliefern.

Hier noch die korrigierte Variante:

Code: Alles auswählen

import Tkinter as tk

class Frameklasse(object):

  def __init__(self, parent, dateninst):
    self.parent = parent
    self.dateninst = dateninst

    self.textlabel = tk.Label(self.parent,
        text=' %s ' % self.dateninst.getData())
    self.textlabel.pack()

# ========================
class datenklasse(object):
 
  def __init__(self):
    self.anzeigestring = 'blablablub'

  def getData(self):
    return self.anzeigestring

  def setData(self, newData):
    self.anzeigestring = newData

# ========================

root = tk.Tk()

dateninstanz = datenklasse()
frameinstanz = Frameklasse(root, dateninstanz)

root.mainloop()
Danke noch für den Hinweis. Sorry für die Irreführung. Sollte nicht mehr passieren!

Gruss wuf :wink:
Take it easy Mates!
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

wuf hat geschrieben:Hallo busfahrer

Danke noch für den Hinweis. Sorry für die Irreführung. Sollte nicht mehr passieren!

Gruss wuf :wink:
Das zeigt doch nur das hinter "wuf" ein Mensch steckt und keine Angst einflössende Maschine :wink:

Gruß...busfahrer
Alles wird gut ;-)
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

Hallo Wuf!

Der Code in meinem Post war nur beispielhaft gedacht, trotzdem danke für die Korrektur! :wink:
Deine Aussagen sind soweit korrekt, die Daten können sich bei mir jedoch auch ohne TopLevel ändern. Aber das nur nebenbei...

Da mein Projekt relativ umfangreich ist und die GUI darüber hinaus auch noch mehrmals und getrennt von der Datenklasse existieren kann (alla Client-Server) werde ich mir wohl ne Routine ausdenken, mit der sich sozusagen die Frames mit ihren Labels, Entrys, usw. über Keywords bei der GUI registrieren und diese sich dann wiederrum in der Datenklasse registriert.
So weiss die Datenklasse, welche Keywords (Datensätze) in der jeweiligen GUI Verwendung finden und kann diese dann gezielt aktualisieren, wenn nötig.
Antworten