Automatisch Werte in einer Tabelle berechnen + Plott

Fragen zu Tkinter.
Antworten
Sabbse92
User
Beiträge: 13
Registriert: Samstag 29. Februar 2020, 20:02

Guten Tag,

ich verwende Python/Tkinter erst vor kurzem und möchte dies für eine Versuchsauswertung benutzen. Der Programm soll wie folgt funktionieren:

1) Der Benuter soll die Anzahl N seiner Messergebnisse eintragen
2) Eine Tabelle mit N Zeilen wird automatisch erzeugt. In die erste Spalte kann der Benutzer seine Messwerte x eingeben
3) Anhand der eingebenen Messwerte x werden in Spalten 2,3 sowie 4 automatisch die Funktionswerte f(x)=x**2, der Mittelwert der Messwerte sowie deren Standardabweichung berechnet.
4) Mit den Messwerten x und den Funktionswerten f(x) wird ein Plott x gegen f(x) (matplotlib) erstellt.

Die Punkte 1),2) werden im unteren Code korrekt ausgeführt.

Ich weiß jedoch nicht, wie der 3) Punkt umgesetzt werden soll. Das Problem ist, dass die Entry-Widgets innerhalb einer Funktion erzeugt werden und somit lokal sind. Um die Werte automatisch mit trace zu berechnen, brauche ich aber globale Variablen.

Bei Punkt 4) stellt sich mir die gleiche Frage. Um die Werte zu erhalten, muss ich .get() verwenden. Die Variablen sind aber wieder lokal...

Hat jemand von euch eine Idee, wie man die Punkte 3)/4) umsetzen kann?



Stark vereinfachter Beispiel Code der die Punkte 1)/2) erfüllt:

Code: Alles auswählen

from functools import partial
import tkinter as tk

def create_rows(name, index, mode, root=None, eingabe=None):
    try:
        rows = eingabe.get()
    except tk.TclError:
        pass
    else:
        for j in range(2):
            for i in range(rows):
                if j == 0:
                    tk.Entry(root).grid(row=i+2, column=j)
                else:
                    tk.Entry(root, state = "disabled", disabledforeground="black", disabledbackground="white").grid(row=i+2, column=j)
                    
    mittelwert_entry = Entry(root, state = "disabled", disabledforeground="black", disabledbackground="white").grid(row = rows - 1, column=2)
    std_entry = Entry(root, state = "disabled", disabledforeground="black", disabledbackground="white").grid(row = rows - 1, column=3)

def main():
    root = tk.Tk()
    tk.Label(root, text = "Number of measurements:").grid(row=0, column=0, pady=20, padx = 5)
    tk.Label(root, text = "x").grid(row=1, column=0)
    tk.Label(root, text = "f(x)=x**2").grid(row=1, column=1)
    tk.Label(root, text = "Mittelwert x").grid(row=1, column=2, padx = 10)
    tk.Label(root, text = "Standardabweichung x").grid(row=1, column=3, padx = 10)
    
    eingabe = tk.IntVar(root)
    eingabe.trace('w', partial(create_rows, root=root, eingabe=eingabe))
    tk.Entry(root, textvariable=eingabe).grid(row=0, column=1)

    root.mainloop()

if __name__ == '__main__':
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 14087
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sabbse92: Lern am besten erst einmal Python, bis einschliesslich Klassen, ohne GUI. Denn das ist alles Voraussetzung für jede nicht-triviale GUI.

Und dann ist das mit `trace()` und wie da die Elemente erstellt werden falsch. Das wurde Dir ja bereits in einem anderen Thema gesagt. Du darfst da nicht immer bei jeder Änderung *alle* Elemente erstellen, sondern nur die erstellen oder löschen die sich seit der letzten Änderung der Eingabe geändert haben. Das ist aber alles fürchterlich kompliziert für einen Anfänger, also lass am besten erst einmal solche unsinnigen Spielereien bleiben und lass den Benutzer die Zahl eingeben, beispielsweise in einem Dialog, und erstelle die Elemente nachdem der Benutzer die Anzahl eingegeben und den Dialog bestätigt hat. Für so simple Eingaben wie eine Zahl gibt es in `tkinter.simpledialog` passende Funktionen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sabbse92
User
Beiträge: 13
Registriert: Samstag 29. Februar 2020, 20:02

Gut, ich versuche erst einmal auf das "automatische" Erstellen zu verzichten, bis mich besser mit der Thematik auskenne.
....und lass den Benutzer die Zahl eingeben, beispielsweise in einem Dialog, und erstelle die Elemente nachdem der Benutzer die Anzahl eingegeben und den Dialog bestätigt hat. Für so simple Eingaben wie eine Zahl gibt es in `tkinter.simpledialog` passende Funktionen.
Ich habe mir die doc zu simpledialog durchgelesen, verstehe aber nicht, wie nach der Eingabe eine Tabelle erzeugt wird. Angenommen die Tabelle hat 6 Spalten (fest) und der Benutzer kann die Anzahl der Zeilen eingeben. Kannst du mir anhand dieses Beispiel zeigen, wie man simpledialog verwenden muss. Ich würde diese Idee übernehmen und damit versuchen den Plott zu erstellen.
Benutzeravatar
__blackjack__
User
Beiträge: 14087
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sabbse92: Tabelle erzeugen hast Du doch schon in Deinem Code. Mittels `grid()`-Layout.

Wobei es natürlich noch einfacher wäre, wenn man alles im Hauptfenster erledigt. Einen `Frame` mit der Frage nach der Anzahl der Werte, ein `Entry` dafür, und einen Ok-`Button`. Und wenn der dann gedrückt wird und das `Entry` einen gültigen Wert hat, kann man `Entry` und `Button` deaktivieren, und in einem weiteren `Frame` darunter dann die Tabelle aufbauen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sabbse92
User
Beiträge: 13
Registriert: Samstag 29. Februar 2020, 20:02

Danke für die Erklärung.

Dann versuche ich es mal so umzusetzen!
Antworten