Menüfenster, Fenster in Fenster, Weiterleitung zu Fenster

Fragen zu Tkinter.
Antworten
silvapuer
User
Beiträge: 7
Registriert: Dienstag 11. Februar 2020, 16:41

Hallo, ich habe tkinter einwenig ausprobiert und einen kleinen Taschenrechenr Programmiert.
jetz wollte ich das Programm "sauber" schreiben, also mit OOP und bin dabei auf folgendes Problem gestoßen:
ich will, dass der Taschenrechner ein Hauptfenster (root, bzw mainframe) hat, mit 5 Buttons oben (RUN, GRAPH, GEOM, PHYS) und dass, jenachdem, auf welchen button
man klickt unterhalb im "workframe" ein durch die Klasse "RUN", "GRAPH",... initialisierter/aufgerufener Bereich vergleichbar mit einem Fenster im Fenster aufgeht.

Code: Alles auswählen

from tkinter import Tk, Frame, Button, Text, Scrollbar, INSERT, NS, EW, StringVar
from sympy import *

class CALCULATOR:

    def __init__(self, master):
        self.master = master
        master.title("CALCULATOR")

        self.MENU = StringVar()
        self.MENU.set("MATH")

        self.mathButton = Button(master, text="MATH", command=self.MENU.set("MATH"))
        self.graphButton = Button(master, text="GRAPH", command=self.MENU.set("GRAPH"))
        self.geomButton = Button(master, text="GEOM", command=self.MENU.set("GEOM"))
        self.physButton = Button(master, text="PHYS", command=self.MENU.set("PHYS"))

        self.WFroot = Frame(master)
        self.WFroot.pack()
        #scenehandler
        if self.MENU == "MATH":
            self.workframe = MATH(self.WFroot)

        elif self.MENU == "GRAPH":
            #self.workframe = GRAPH(self.WFroot)
            pass
        elif self.MENU == "GEOM":
            #self.workframe = GEOM(self.WFroot)
            pass
        elif self.MENU == "PHYS":
            #self.workframe = PHYS(self.WFroot)
            pass
        else:
            pass

class MATH:
    def __init__(self, master):
        #Widgets erstellen
        self.master = master
        self.cframe = Frame(root)
        self.console = Text(self.cframe, height=10, width=50, bd=1)
        self.scroll = Scrollbar(self.cframe, orient="vertical", command=self.console.yview)
        #Widgets konfiurieren
        self.console.tag_configure("tag_right", justify="right")
        self.console.config(yscrollcommand=self.scroll.set)
        self.console.bind('<KeyPress-Return>', self.EXE)
        #Widgets visualisiren
        self.console.grid(column=0, row=2)
        self.console.focus()
        self.scroll.grid(column=1,row=2, sticky=NS)

    def EXE(self, event):
        self.curr_line = int(self.console.index(INSERT).split(".")[0])
        self.eingabe = self.console.get(str(self.curr_line)+".0", str(self.curr_line)+".end")
        if len(self.eingabe) > 0:
            if not self.eingabe[0].isalnum():
                self.eingabe=str(self.console.get(str(self.curr_line-1)+".0", str(self.curr_line-1)+".end"))+self.eingabe
        else:
            self.eingabe = "0"
            self.console.insert(str(self.curr_line)+".0", self.eingabe)
        try:
            self.ausgabe= str(eval(self.eingabe))
        except:
            self.ausgabe = "0"

        self.console.delete(str(self.curr_line+1)+".0", str(self.curr_line+1)+".end") #vorheriges ergebnis löschen, falls vorhanden
        self.console.insert(str(self.curr_line+1)+".0 -1c", "\n"+self.ausgabe, "tag_right") #neues ergebnis an diese stelle einfügen
        self.console.delete(str(self.curr_line+2)+".0 -1c", str(self.curr_line+2)+".end")
        self.console.delete("end -1c", "end")
        self.console.mark_set("insert", "end")

root = Tk()
window = CALCULATOR(root)
root.mainloop()
die if-Anweisung in der CALCULATOR Klasse soll die unterfenster aufrufen. es kommt kein Error, aber wenn man es debugt, wird das Run_Fenster auch nicht angezeigt, sondern nur ein winziges, leeres tk
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@silvapuer: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Da sind einige Namen also formal falsch geschrieben.

Sternchen-Importe sind Böse™. Aus `sympy` wird in dem Quelltext auch gar nichts verwendet.

Nicht alles was aus `tkinter` importiert wird, wird auch tatsächlich verwendet.

Das `master`-Attribut von beiden Klassen wird nirgends verwendet.

Bei den Buttons wird als `command` der Rückgabewert von `self.MENU.set()` übergeben – das heisst das wird *ausgeführt* bevor der Button überhaupt erstellt wurde, und der Rückgabewert ist sicher nichts aufrufbares, was `command` aber erwartet. Da könntest Du mal einen Blick auf `functools.partial()` werfen.

Das ``if``/``elif``-Konstrukt ist in zweifacher hinsicht falsch. A) zu dem Zeitpunkt wo Du den Inhalt von `self.MENU` auswerten möchtest hatte der Benutzer ja noch gar keine Möglichkeit irgend etwas auszuwählen. Und B) vergleichst Du das `StringVar`-Objekt mit Zeichenketten, was niemals gleich sein wird.

GUIs werden normalerweise auch am Anfang einmal erzeugt, also nicht erst wenn man auf den MATH-Button drückt, sondern schon vorher, und der Button macht die vorhandene GUI dann nur sichtbar. Bevor man da selbst was programmiert, sollte man erst einmal schauen ob's nicht auch ein `ttk.Notebook` tut.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten