Button soll via Lambda zwischen Frames wechseln, anscheinend deute ich das Objekt aber falsch

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
syrrokzu
User
Beiträge: 5
Registriert: Samstag 14. September 2019, 19:27

Okay hallo! Zu mir etwas kuzes, ich bringe vielseitige Programmiererfahrungen aus sämtlichsten Sprachen mit, aber nur bis zu einem gewissen Grade denn ich bin bei keiner Sprache länger geblieben und habe nicht wirklich professionell programmiert, bin noch dazu recht neu in Python aber ich versuche mein bestes mein Problem zu beschreiben.

Folgendes Konstrukt:

class Application
-def __init__(...)
- container
-frame
-def show_frame .....

class StartPage
-def __init__(...)
-frame
-label
-button(command=lambda: controller.show_frame()

class pageOne
-label


Application ist das Grundgerüst und beinhaltet Funktion show_frame.
Beim Öffnen wird StartPage geladen.
StartPage enhält lediglich ein Label als Platzhalter und einen Button als Funktionstest. Der Button soll über sein command eine Lambda funktion für show_frame aus class Application ausführen.
PageOne enhält lediglich ein Label mit unterschiedlichen Text als Bestätigung des Wechsels.

Pastebin-Link zum Code

Dieses kleine Konstrukt ist soweit im Code meinerseits auch fehlerfrei, bis man den Button für den Frame-Wechsel (Seitenwechsel) drückt, dann kommt folgende Fehlermeldung im Interpreter zurück:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Stiebler\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "G:\Development\SeaofBTC\main.py", line 39, in <lambda>
command=lambda: controller.show_frame(PageOne))
File "G:\Development\SeaofBTC\main.py", line 28, in show_frame
frame = self.frames[cont]
KeyError: <class '__main__.PageOne'>
Wo ist mein Fehler hier? Offensichtlich liegt der Ursprung des Fehlers wohl in Zeile 28, dort verwende ich anscheinend irgendein Objekt oder Parameter falsch, was dann wiederum beim Aufruf bei Button-Klick den Fehler generiert da er das deutende Objekt und die dazugehörige Funktion show_frame nicht findet, und der Fehler taucht davor nicht auf da diese Funktion bis zum Aufruf durch des Buttons nicht verwendet wird.

PS: extrem vereinfacht und Code reduziert auf ein Minimum
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@syrrokzu: Bitte zeig den Code hier im Forum, sonst muss man erst woanders schauen und hoffen das der Code dort auch bleibt und auch nicht im Laufe der Zeit verändert wird und nicht mehr zur Frage passt.

Code: Alles auswählen

import tkinter as tk

SMALL_FONT = ("Verdana", 10)
MEDIUM_FONT = ("Verdana", 12)
LARGE_FONT = ("Verdana", 16)


class SeaofBTCapp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        frame = StartPage(container, self)
        self.frames[StartPage] = frame

        frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Start Page", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = tk.Button(
            self,
            text="Visit Page 1",
            command=lambda: controller.show_frame(PageOne),
        )
        button1.pack()


class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="PageOne", font=LARGE_FONT)
        label.pack(pady=10, padx=10)


app = SeaofBTCapp()
app.mainloop()
Was genau wundert Dich denn da jetzt? Beschreib doch mal wie der Code abläuft und an welcher Stelle im Programmablauf er sich dann nicht mehr so verhält wie Du das erwartest und warum Du das unerwartet findest‽ Ich habe den Verdacht das Dir einfach Grundlagenwissen fehlt und dieses Konstrukt irgendwo abgeschrieben wurde, denn das kommt mir sehr bekannt vor.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
syrrokzu
User
Beiträge: 5
Registriert: Samstag 14. September 2019, 19:27

Hallo Blackjack, danke für deine.. Rückmeldung.

Du schriebst:
Was genau wundert Dich denn da jetzt? Beschreib doch mal wie der Code abläuft und an welcher Stelle im Programmablauf er sich dann nicht mehr so verhält wie Du das erwartest und warum Du das unerwartet findest‽ Ich habe den Verdacht das Dir einfach Grundlagenwissen fehlt und dieses Konstrukt irgendwo abgeschrieben wurde, denn das kommt mir sehr bekannt vor.
Was mich zu den Verdacht bringt du hättest meinen Post nicht mal einen millimeter gelesen.

Den Code hatte ich absichtlich in einen pastebin hinterlegt um meinen Beitrag übersichtlicher zu gestalten. Außerdem fand ich keinerlei Code-Funktion oder Spoiler-Funktion im Text-Editor auf der Seite, und verstehe auch nachwievor nicht wie du den Text als Code markiert hast da es mir nicht direkt ersichtlich ist.

(Zu meinen fehlenden Grundlagenwissen schrieb ich bereits folgendes.)
Okay hallo! Zu mir etwas kuzes, ich bringe vielseitige Programmiererfahrungen aus sämtlichsten Sprachen mit, aber nur bis zu einem gewissen Grade denn ich bin bei keiner Sprache länger geblieben und habe nicht wirklich professionell programmiert, bin noch dazu recht neu in Python aber ich versuche mein bestes mein Problem zu beschreiben.
(Zum Programmablauf schrieb ich bereits folgendes:)
Application ist das Grundgerüst und beinhaltet Funktion show_frame.
Beim Öffnen wird StartPage geladen.
StartPage enhält lediglich ein Label als Platzhalter und einen Button als Funktionstest. Der Button soll über sein command eine Lambda funktion für show_frame aus class Application ausführen.
PageOne enhält lediglich ein Label mit unterschiedlichen Text als Bestätigung des Wechsels.
(Den Fehler der auftaucht notierte ich auch, und meine Theorie ebenfalls...)
Wo ist mein Fehler hier? Offensichtlich liegt der Ursprung des Fehlers wohl in Zeile 28, dort verwende ich anscheinend irgendein Objekt oder Parameter falsch, was dann wiederum beim Aufruf bei Button-Klick den Fehler generiert da er das deutende Objekt und die dazugehörige Funktion show_frame nicht findet, und der Fehler taucht davor nicht auf da diese Funktion bis zum Aufruf durch des Buttons nicht verwendet wird.
Und das es dir bekannt vorkommt.. Mhh, vielleicht weil es im Prinzip nichts außer Ein Button, zwei Labeln und ein Frame ist?.. Und wenn es bekannt wäre, dann würde der Code wohl funktionieren.

Sorry falls ich "grob" daherkomme nun, aber wirklich. Alles was du angesprochen hast habe ich sogar deutlicher geschrieben als 99% der Beiträge von Besuchern die in ihren Forum-Leben 1-2 Beiträge schreiben und dann haben was sie wollen. Du mit deinen 4003 Beiträgen in diesen Forum verhälst dich aufjedenfall nicht gerecht in diesen Fall.
Finde ich super als Neuling direkt hier so aufgenommen zu werden, jemand, der nicht richtig liest und schön daher kommt. Trotzdem danke.
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Also mir kommt der Code bekannt vor, weil er hier https://pythonprogramming.net/change-sh ... e-tkinter/ steht, und funktioniert.

Du hast daraus relevante Teile entfernt, vor allem die Anlage eines PageOne-Frames. Auf den du dann wechseln willst. Das klappt halt nicht. Man muss schon Dinge in ein Wörterbuch packen, damit man sie danach darin nachschlagen kann.

Die geheime Funktion zur Darstellung von Code verbirgt sich hinter dem ominösen </>-Knopf. Direkt neben dem Zitat-Knopf, bis zu dem du es ja erfolgreich geschafft hast.
syrrokzu
User
Beiträge: 5
Registriert: Samstag 14. September 2019, 19:27

Der gepostete Code ist mir ebenfalls nicht bekannt. Ein Page-One Frame habe ich doch ebenfalls erstellt... Mit for-schleifen habe ich bisher auch noch nie gearbeitet und ich rufe noch nichtmal den Controller in den inits auf. Mein Code ist komplett unterschiedlich, ich werde mich nun an den geposteten Orientieren. Zu guter Letzt würde er ja wohl auch funktionieren wenn ich ihn von dort hätte? Oder würde ich als Neuling bei Copy-Paste sachen einfach was entfernen und in nem Forum gehen, dann aber so detailiert schreiben und verfassen? Aber für die Zukunft:

hereinzuplatzen und es als kopiert und verschändelt zu bezeichnen ohne das man den Hintergrund weiß ist nur lächerlich. Dreckige Menschheit.
Imemr mehr und mehr Menschen meiden wegen Leuten wie euch Foren und gehen mit Problemen immer weniger an die Öffentlichkeit weil eh alles nur ins lächerliche gezogen wird und jeder denkt er weiß alles.

Ich habe meine Variante des Konstruktes gepostet, wollte dazu eine Antwort. Ihr platzt rein mit euren Fachwissen, mit den ihr eine 2 Zeilige, entte Antwort erstellen könntet aber stattdessen lasst ihr den ... raushängen. Traurig. Habe euch beide gemeldet, eure Antworten gehen komplett am Thema vorbei, ignorieren sämtliches von mir, zeit-intensives geschriebenes und eure Antworten sind unfreundlich und unpassend und beinhalen in dem Sinne "beschuldigungen". -- "Hast du wo abgeschrieben" - und ganz ehrlich, selbst wenn - wie habt ihr denn gelernt? Ihr wusstet ja auch alles im vorhinein und habt nicht wo anders mal was angeschaut und nachgebaut? Habe auf Basis einer Dokumentation meinen oben stehenden Code erschaffen, Begrifflichkeiten und Benenunngen von da übernommen. Leider war das kein Tutorial oder Fertig-Code, somit stand ich dann da. Ähnlichkeiten des Codes kommen eventuell daher das ich mir grundlegend, wie eräwhnt, andere Ressourcen anschaue, das mit den Schriften im vorhinein deklarieren habe ich von sonst wo. Ansonsten ähnelt sich auch nur der sonst immer gleiche Tkinter-Aufbau... aber ihr wissts ja besser.

Im Endeffekt wollte ich eher hierherkommen und fragen WARUM mein Code nicht funktioniert und nicht WIE ich es einfügen muss. Ich will ja was lernen, und das jetzt in dem geposteten Tutorial deinerseits nachzuschauen wäre für mich eher ein Verlust... Dann funktioneirts und ich weiß trotzdem nicht warum.

War ne super idee Python zu lernen und darauf zu hoffen im forangehenden Prozess bei Problemen mal nette Antworten zu erwarten.

PS: Nachwievor, wenn mir jemanden sagen kann was ich in oben geposteten Code falsch gemacht habe bzw was dort schief läuft wäre ich sehr dankbar.....
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@syrrokzu: Dein Code ist komplett unterschiedlich‽ Ääähh… nein ist er nicht!

Eine zweizeilige ”nette” Antwort wird Dir nicht helfen, weil das Problem nicht in zwei Zeilen zu behandeln ist. Und da Du hier kopierten Code zeigst – das kannst Du gerne soviel abstreiten wie Du möchtest, das ist halt einfach *offensichtlich* – weiss man halt auch nicht wo man anfangen muss. Vielleicht hast Du auch von woanders abgeschrieben wo jemand von dort abgeschrieben hat, oder auch von dem Stackoverflow-Artikel von dem der Blogpost abgeschrieben hat. Der Code ist jedenfalls viel zu ähnlich als das er nicht kopiert wurde, denn das ist auch nicht der „immer gleiche Tkinter-Aufbau“.

Ich habe nicht durch kopieren von Code gelernt den ich nicht verstehe, denn dadurch lernt man nichts. Natürlich habe ich mir auch öfter mal Code angeschaut der das gemacht hat was ich lernen wollte, aber ich habe den nie abgeschrieben oder gar kopiert, ohne ihn zu verstehen.

Du hattest etwas zum Programmablauf geschrieben, ja, aber ich fragte nach weil das nicht detailliert genug war. Da steht nicht Schritt für Schritt, Zeile für Zeile was passiert bzw. was Du glaubst was passiert, und wann welcher Stelle das dann konkret nicht mehr das macht was Du erwartest und warum Du da etwas anderes erwartet hast. Das ist genau das was man als Programmierer machen muss: Man hat eine Vorstellung davon was passiert, dann passiert aber was anderes. Und dann muss man als erstes überprüfen/herausfinden wo die Realität von der Erwartung abweicht, und inwiefern sie das tut.

Das Problem ist hier eigentlich sehr offensichtlich. Wenn man Python-Grundlagen kann. Allerdings braucht man da wirklich die kompletten Grundlagen, also inklusive objektorientierter Programmierung (OOP) *und* ereignisbasierter Programmierung die man bei GUIs hat. OOP baut auf Funktionen auf. Und dazu muss man dann noch mit den Grunddatentypen von Python umgehen können. Das Problem wurde ja bereits genannt: Ein `PageOne`-Exemplar wurde nicht erstellt und auch nicht als Wert zur Klasse als Schlüssel in das Wörterbuch (`frames`-Attribut von `Application`-Exemplaren) gesteckt. Nur nützt Dir die Antwort wenig wenn Du die Grundlagen nicht kannst. Wir können Dir nicht abnehmen die Grundlagen selbst zu lernen. Das musst Du Dir selbst erarbeiten, das kann Dir keiner in den Kopf beamen.

Was ist denn die/Deine Quelle von dem Code?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich habe dir gesagt, was die Ursache ist. Und sogar Code gezeigt, der offensichtlich durch ein Wunder ganz ganz ganz nah an dem ist, was du probierst. Freu dich doch! Aber offensichtlich ist das Bedürfnis sich wortreich über die Übel der Welt zu beklagen, Leute zu melden, Unterstellungen zu fertigen und sich ganz allgemein auf den Schlips getreten zu fühlen so groß, das man das gar nicht wahrnehmen kann 🤷🏼‍♂️
Antworten