Daten zwischen Klassen austauschen

Fragen zu Tkinter.
Antworten
sc19
User
Beiträge: 10
Registriert: Samstag 18. Dezember 2021, 15:09

Hallo,
Ich versuche mich in die objektorientierte Programmierung, im folgenden der einfachheitshalber OOP genannt einzuarbeiten.
Soweit ich das verstanden habe, dient die OOP den Programmcode strukturierter zu machen. Um u.a. die Wartung zu vereinfachen, wird das Programm in kleinere Module, sprich Klassen aufgeteilt.
Nach diesem Prinzip versuche ich schon seit Tagen etwas zu programmieren. Leider habe ich es bisher nicht geschafft/verstanden, wie ich Daten/Werte zwischen den Klassen austauschen kann. Ich habe hier mal ein einfaches Beispiel mit 3 Klassen gebastelt und versuche hier die in der Klasse class MainWindow(tk.Tk):
Variable self.name_var = tk.StringVar() auch in den anderen beiden Klassen zu benutzen. Ja und genau an der Stelle komme ich nicht weiter.

Hier der Programmcode:

Code: Alles auswählen

import tkinter as tk

class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Datenaustasuch zwischen Klassen')
        self.geometry("500x300")
        self.resizable(False, False)

        tk.Label(self, text='Name:').grid(column=0, row=0)
        self.name_var = tk.StringVar()
        name_entry = tk.Entry(self, textvariable=self.name_var)
        name_entry.grid(column=1, row=0)
        name_entry.focus()

        submit_button = tk.Button(self, text='Submit', command=self.submit)
        submit_button.grid(column=2, row=0)

        self.output_label = tk.Label(self)
        self.output_label.grid(column=0, row=1, columnspan=3)

    def submit(self):
        self.output_label.config(text=self.name_var.get())


class Class2(tk.Frame):
    def __init__(self,master):
        tk.Frame.__init__(self)

        self.label_class2 = tk.Label(self)
        self.label_class2.grid(column=0, row=2, columnspan=3)
        self.label_class2.config(text= self.name_var.get())

class Class3(tk.Frame):
    def __init__(self,master ):
        tk.Frame.__init__(self)

        self.label_class3 = tk.Label(self)
        self.label_class3.grid(column=0, row=3, columnspan=3)
        self.label_class3.config(text= self.name_var.get())

def main():
    root = MainWindow()
    root.mainloop()

if __name__ == "__main__":
    main()
Es würde mich sehr freuen, wenn mir das einer verständlich erklären könnte.
Liebe Grüße
sc19
Benutzeravatar
__blackjack__
User
Beiträge: 13199
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@sc19: Wenn eine Funktion oder Methode etwas braucht was keine Konstante ist, dann übergibt man das als Argument. Bei Methoden eventuell über das `self` wenn es ein Attribut der Klasse ist, sonst halt ganz normal beim Aufruf explizit als Argument.

Du musst beim `Frame.__init__()`-Aufruf auch `master` übergeben, sonst ”sucht” sich das Widget das Hauptfenster, was nicht immer gewollt ist, und was man nicht ändern kann, wenn man das Argument nicht ordnungsgemäss weiter reicht.

Der Titel/die Frage ist auch ein bisschen irreführend, weil es nicht um den Datenaustausch zwischen Klassen geht, sondern zwischen Objekten (die aus Klassen erstellt wurden).
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
sc19
User
Beiträge: 10
Registriert: Samstag 18. Dezember 2021, 15:09

Erst einmal Danke für Deine Mühe. Leider habe ich es offensichtlich noch nicht so recht verstanden. ich erhalte folgende Fehlermeldung:
self.label_class2.config(text= self.name_var.get())
AttributeError: 'Class2' object has no attribute 'name_var'

Es wäre sehr hilfreich, wenn der Programmcode von mir entsprechend korrigiert werden könnte. Ich vermute mal, dass es nur wenige Zeilen Code ist, die korrigiert bzw. ergänzt werden müssen.
Benutzeravatar
__blackjack__
User
Beiträge: 13199
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@sc19: Die Fehlermeldung ist ja recht eindeutig. Wo auch immer diese Zeile steht, musst Du das `StringVar`-Objekt halt beim Aufruf übergeben.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Sirius3
User
Beiträge: 17793
Registriert: Sonntag 21. Oktober 2012, 17:20

@sc19: Dein Code funktioniert einwandfrei, weil Class2 gar nirgends gebraucht wird. Die Fehlermeldung, die Du bekommst, stammt also nicht aus Deinem gezeigten Code, entsprechend können wir den auch gar nicht korrigieren.
sc19
User
Beiträge: 10
Registriert: Samstag 18. Dezember 2021, 15:09

Also ich möchte hier keine NeverEnding Diskussion eröffnen und nochmals auf mein ursprünglich gestellte Frage verweisen. Die beiden Kommentare bisher sind leider kein bisschen hilfreich und schade, dass man Kommentare hier nicht bewerten kann. Offensichtlich haben hier einige Kommentatoren viel spaß daran, sich über die Fehler der Neulinge lustig zu machen. Denn ich bin mir sicher, dass die Korrektur bzw. die Ergänzung meines Beispielcodes viel weniger Zeit gekostet hätte. Bewusst habe darauf hingewiesen, dass ich es nicht verstanden habe und das sollte eigentlich den Reiz sich über jemandes Fehler lustig zu machen nehmen dachte ich mir.
Benutzeravatar
pillmuncher
User
Beiträge: 1485
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@sc19: Hier hat sich niemand über dich lustig gemacht. Im Gegenteil, man hat dir gesagt, warum dein Code nicht funktioniert und sogar, wie du das beheben kannst. Siehe die Antworten von __blackjack__. Wenn du diese nicht verstehst, dann könnte das daran liegen, dass du die Grundlagen noch nicht beherrschst. Das ist nicht schlimm. Jeder hat mal damit angefangen, die Grundlagen zu lernen. Zum Beispiel, indem man das offizielle Tutorial durchgearbeitet hat. Das kann dir keiner abnehmen, und es hätte auch keinen Sinn, es dir hier im Forum schriftlich vorzulesen, denn damit würde man nur kopieren, was bereits an anderer Stelle steht.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
sparrow
User
Beiträge: 4231
Registriert: Freitag 17. April 2009, 10:28

sc19 hat geschrieben: Donnerstag 23. Dezember 2021, 20:39 Ich versuche mich in die objektorientierte Programmierung, im folgenden der einfachheitshalber OOP genannt einzuarbeiten.
Soweit ich das verstanden habe, dient die OOP den Programmcode strukturierter zu machen. Um u.a. die Wartung zu vereinfachen, wird das Programm in kleinere Module, sprich Klassen aufgeteilt.
Da bringst du ein bisschen was durcheinander. Objektorientierte Programmierung ist ein Konzept, das nicht zwangsläuftig dazu führt, dass Code strukturierter ist.
Klassen sind keine zwingenden "Behälter" für Code - so klingt es bei dir - auch wenn es Programmiersprachen gibt, die das erzwingen.
"Module" hingegen haben in Python eine andere Bedeutung und mit Objektorientierung nichts zu tun.


Offensichtlich hast du vor lauter Aufregung die sehr hilfreiche Antwort überlesen, dass der Code, den du hier zeigst, nichts mit dem Code zu tun hat, der deine Fehlermeldung verursacht. Man fährt ja auch nicht mit dem grünen Auto in die Werkstatt, weil bei dem roten die Bremse komische Geräusche macht.
sc19
User
Beiträge: 10
Registriert: Samstag 18. Dezember 2021, 15:09

das beste wird wohl sein, sich ganz schnell wieder von diesem Forum zu trennen. Das war mein 2. und letzter Beitrag hier.
Schlagt euch die Köpfe ein, oder macht damit sonst was ihr wollt.
Benutzeravatar
__blackjack__
User
Beiträge: 13199
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@sc19: Ich denke auch Du missverstehst hier etwas und projezierst auch *Deine* Frustration auf uns. Warum sollten wir uns die Köpfe einschlagen? Ich hatte nicht den Eindruck das hier irgendwer aggressiv ist — ausser Du jetzt so ein bisschen.

Es konnte auch keiner schneller Deinen Code korrigieren oder ergänzen, als eine Antwort zu schreiben, weil gar nicht so wirklich klar ist, was da wo genau ergänzt werden soll, ohne zu wissen was Du da eigentlich vor hast. Ohne dieses Wissen kann man nur sagen, dass alles was eine Funktion oder Methode ausser Konstanten benötigt, als Argument übergeben werden muss. Aus Deinen Codeschnippseln wird nicht ersichtlich wo so ein `Class*`-Objekt erzeugt werden soll. *Dort* musst Du das `StringVar`-Objekt übergeben. Und Du kannst Dich darauf nicht über `self` beziehen solange das nicht als Attribut auf diesem Objekt existiert. Das kann man vorher natürlich daran binden, aber auch hier wissen wir wieder nicht ohne weiteren Kontext ob das überhaupt Sinn macht.

Letztlich ist es IMHO auch eine gute Idee sich OOP erst mal ohne die zusätzliche Komplexität von GUI-Programmierung anzuschauen. Dann muss man sich nicht mit zwei grösseren Themen gleichzeitig auseinandersetzen.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Antworten