Scrollbar im falschen frame

Fragen zu Tkinter.
Antworten
gerdk
User
Beiträge: 12
Registriert: Freitag 17. Februar 2023, 19:52

Hallo, bei folgendem Programm funktioniert die ScrolBar im "ergebnis_frame" (soll da nicht sein),
nicht jedoch in dem inner_frame, wo die Tabelle erstellt wird.

Was mache ich falsch?

import tkinter as tk
from tkscrolledframe import ScrolledFrame
import math

def validate_number(text):
try:
if text:
_ = float(text.replace(',', ','))

except ValueError:
print("error")
return False
return True


def main(darlehen, zinssatz, rate, zbindung, zins2, sondertilgung):
print("\nTilgungsplan:\n")
print("Monat Zinssatz Tilgung Rest Sumzinsen Sonderz")
summezinsen = 0
monat = 1
rest = float(darlehen)
zins1 = float(zinssatz)

for widget in ergebnis_frame.winfo_children():
widget.grid_forget()

ueberschriften = ["Monat", "Zinssatz", "Tilgung", "Sonderzahlung", "Restschuld"]

for column_index, ueberschriften in enumerate(ueberschriften):
tk.Label(ergebnis_frame, text=ueberschriften,
font="bold").grid(row=0, column=column_index, sticky="e", padx=5)

while rest > 0:
#merkerest = rest
if (monat <= zbindung * 12):
zins = zins1
else:
zins = zins2

zinsen = rest * zins / 1200 # Zinsen berechnen

summezinsen += zinsen
tilgung = rate - zinsen
if tilgung > rest:
tilgung = rest
rest -= tilgung

sonderz = 0
if ((monat % 12) == 0):
sonderz = sondertilgung
if (sonderz > rest):
sonderz = rest
rest -= sonderz

zeilemonat = monat

monat += 1


if math.copysign(1, tilgung) == -1:
print("The number is negative")
fehler = tk.Label(ergebnis_frame, text="Zinssatz zu hoch oder Rate zu niedrig", bg="red")
fehler.grid(row=2, column=0, columnspan=4)
rest = 0


print("%2d" % zeilemonat, " ", end='')
print('\t{0:5.2f}'.format(zins), '\t{0:8.2f}'.format(tilgung),
'\t{0:8.2f}'.format(rest), '\t{0:8.2f}'.format(summezinsen),
'\t{0:4.2f}'.format(sonderz))

labelmonat = tk.Label(ergebnis_frame, background='#CDC2AE', width='3')
labelmonat.grid(row=zeilemonat, column=0, padx='5', pady='5')
labelmonat.config(text="{:.0f}".format(zeilemonat))

labelzinsen = tk.Label(ergebnis_frame, background='#CDC2AE', width='6')
labelzinsen.grid(row=zeilemonat, column=1, padx='5', pady='5')
labelzinsen.config(text="{0:10.2f}".format(zins))

labeltilgung = tk.Label(ergebnis_frame, background='#CDC2AE', width='7')
labeltilgung.grid(row=zeilemonat, column=2, padx='5', pady='5')
labeltilgung.config(text="{0:10.2f}".format(tilgung))

labelsonderz = tk.Label(ergebnis_frame, background='#CDC2AE', width='7')
labelsonderz.grid(row=zeilemonat, column=3, padx='5', pady='5')
labelsonderz.config(text="{0:10.2f}".format(sonderz))

labelrest_kapital = tk.Label(ergebnis_frame, background='#CDC2AE', width='7')
labelrest_kapital.grid(row=zeilemonat, column=4, padx='10', pady='5')
labelrest_kapital.config(text="{0:10.2f}".format(rest))

# Monate in Jahr und Monate
if monat % 12 == 0:
jahr = monat / 12
restmonate = 0
else:
jahr = int(monat / 12)
restmonate = monat % 12

if restmonate == 0:
jahr = jahr - 1
restmonate = 12

print("Jahre = ", jahr, "Restmonate = ", restmonate - 1)

tk.Label(sum_frame, text="Jahre", bg="#FCFFB2").grid(sticky="w", row=2, column=3)
tk.Label(sum_frame, text="Monate", bg="#FCFFB2").grid(sticky="w", row=3, column=3)
tk.Label(sum_frame, text="Summe Zinsen", bg="#FCFFB2").grid(sticky="w", row=4, column=3)

labeljahre = tk.Label(sum_frame, width='7', anchor="e", fg="blue")
labeljahre.grid(row=2, column=1, padx='5', pady='5')
labeljahre.config(text="{:.0f}".format(jahr))

labelmonate = tk.Label(sum_frame, width='7', anchor="e")
labelmonate.grid(row=3, column=1, padx='5', pady='5')
labelmonate.config(text="{:.0f}".format(restmonate - 1))

labelsummezinsen = tk.Label(sum_frame, width='7', anchor="e", fg="red")
labelsummezinsen.grid(row=4, column=1, padx='5', pady='5')
labelsummezinsen.config(text="{0:9.2f}".format(summezinsen))

print(f"Summe Zinsen: {summezinsen:.2f}")


def enter_data():
rest = float(darlehen_entry.get())
zins1 = float(zinssatz_entry.get())
rate = float(rate_entry.get())
zbindung = float(zbindung_entry.get())
zins2 = float(zins2_entry.get())
sondertilgung = float(sondertilgung_entry.get())

main(rest, zins1, rate, zbindung, zins2, sondertilgung)


window = tk.Tk()
window.title("Darlehen zurückzahlen")
window.geometry("900x500")
validation = (window.register(validate_number), '%P')


frame = tk.LabelFrame(text="Eingabe", width=400, height=400)
frame.pack(side=tk.LEFT, anchor="n", padx=5, pady=5)

eingabe_frame = tk.LabelFrame(frame, relief='raised', text="Eingabefelder")
eingabe_frame.grid(row=0, column=0, sticky="n", padx=5, pady=5)

sum_frame = tk.LabelFrame(eingabe_frame, text="Ergebnis zusammengefaßt",
width=200, height=200, relief='raised')
sum_frame.grid(row=10, column=0, sticky="news", padx=5, pady=5, columnspan=3)

darlehen_label = tk.Label(eingabe_frame, anchor="w", text="Darlehen", width=15, padx=15)
darlehen_label.grid(row=1, column=0)

zinssatz_label = tk.Label(eingabe_frame, anchor="w", text="Zinssatz", width=15)
zinssatz_label.grid(row=2, column=0)

rate_label = tk.Label(eingabe_frame, anchor="w", text="Rate", width=15)
rate_label.grid(row=3, column=0)

zbindung_label = tk.Label(eingabe_frame, anchor="w", text="Zinsbindung (Jahre)", width=15)
zbindung_label.grid(row=4, column=0)

zins2_label = tk.Label(eingabe_frame, anchor="w", text="Zinssatz nach Bindung", width=15)
zins2_label.grid(row=5, column=0)

sondertilgung_label = tk.Label(eingabe_frame, anchor="w", text="jährl. Sondertilgung", width=15)
sondertilgung_label.grid(row=6, column=0)

sondertilgung_entry = tk.DoubleVar()
sondertilgung_entry.insert = (0)


darlehen_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
zinssatz_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
rate_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
zbindung_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
zins2_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
sondertilgung_entry = tk.Entry(eingabe_frame, textvariable=sondertilgung_entry, width=6, validate="key", validatecommand=validation)


darlehen_entry.grid(row=1, column=2)
zinssatz_entry.grid(row=2, column=2)
rate_entry.grid(row=3, column=2)
zbindung_entry.grid(row=4, column=2)
zins2_entry.grid(row=5, column=2)
sondertilgung_entry.grid(row=6, column=2)


sf = ScrolledFrame(width=700, height=800)
sf.pack()
inner_frame = sf.display_widget(tk.Frame)

sf.bind_arrow_keys(inner_frame)
sf.bind_scroll_wheel(inner_frame)
frame = tk.LabelFrame(inner_frame, text="Ergebnis")
frame.pack(side=tk.TOP, anchor="n", padx=5, pady=5)

ergebnis_frame = tk.LabelFrame(frame, text="Monate Ergebnis / Jahre",
width=500, height=500, relief='raised')
ergebnis_frame.grid(row=1, column=0, sticky="ne", padx=5, pady=5)

button = tk.Button(eingabe_frame, text="rechne", bg="gray", fg="blue", command=enter_data)
button.grid(row=1, column=4, sticky="news", padx=20, pady=10)

window.mainloop()
gerdk
User
Beiträge: 12
Registriert: Freitag 17. Februar 2023, 19:52

sorry, keinen BBCode verwendet

Code: Alles auswählen

import tkinter as tk
from tkscrolledframe import ScrolledFrame
import math

def validate_number(text):
    try:
        if text:
            _ = float(text.replace(',', ','))
            
    except ValueError:
        print("error")
        return False
    return True


def main(darlehen, zinssatz, rate, zbindung, zins2, sondertilgung):
    print("\nTilgungsplan:\n")
    print("Monat Zinssatz    Tilgung         Rest   Sumzinsen     Sonderz")
    summezinsen = 0
    monat = 1
    rest = float(darlehen)
    zins1 = float(zinssatz)
    
    for widget in ergebnis_frame.winfo_children():
        widget.grid_forget()
              
    ueberschriften = ["Monat", "Zinssatz", "Tilgung", "Sonderzahlung", "Restschuld"]

    for column_index, ueberschriften in enumerate(ueberschriften):
        tk.Label(ergebnis_frame, text=ueberschriften,
                 font="bold").grid(row=0, column=column_index, sticky="e", padx=5)

    while rest > 0:
        #merkerest = rest
        if (monat <= zbindung * 12):
            zins = zins1
        else: 
            zins = zins2
            
        zinsen = rest * zins / 1200  # Zinsen berechnen

        summezinsen += zinsen
        tilgung = rate - zinsen
        if tilgung > rest:
            tilgung = rest
        rest -= tilgung
        
        sonderz = 0
        if ((monat % 12) == 0):
            sonderz = sondertilgung
            if (sonderz > rest):
                sonderz = rest
        rest -= sonderz

        zeilemonat = monat
        
        monat += 1
        
            
        if math.copysign(1, tilgung) == -1:
            print("The number is negative")
            fehler = tk.Label(ergebnis_frame, text="Zinssatz zu hoch oder Rate zu niedrig", bg="red")
            fehler.grid(row=2, column=0, columnspan=4)
            rest = 0


        print("%2d" % zeilemonat, "  ", end='')
        print('\t{0:5.2f}'.format(zins), '\t{0:8.2f}'.format(tilgung),
              '\t{0:8.2f}'.format(rest), '\t{0:8.2f}'.format(summezinsen), 
              '\t{0:4.2f}'.format(sonderz))

        labelmonat = tk.Label(ergebnis_frame, background='#CDC2AE', width='3')
        labelmonat.grid(row=zeilemonat, column=0, padx='5', pady='5')
        labelmonat.config(text="{:.0f}".format(zeilemonat))

        labelzinsen = tk.Label(ergebnis_frame, background='#CDC2AE', width='6')
        labelzinsen.grid(row=zeilemonat, column=1, padx='5', pady='5')
        labelzinsen.config(text="{0:10.2f}".format(zins))

        labeltilgung = tk.Label(ergebnis_frame, background='#CDC2AE', width='7')
        labeltilgung.grid(row=zeilemonat, column=2, padx='5', pady='5')
        labeltilgung.config(text="{0:10.2f}".format(tilgung))

        labelsonderz = tk.Label(ergebnis_frame, background='#CDC2AE', width='7')
        labelsonderz.grid(row=zeilemonat, column=3, padx='5', pady='5')
        labelsonderz.config(text="{0:10.2f}".format(sonderz))

        labelrest_kapital = tk.Label(ergebnis_frame, background='#CDC2AE', width='7')
        labelrest_kapital.grid(row=zeilemonat, column=4, padx='10', pady='5')
        labelrest_kapital.config(text="{0:10.2f}".format(rest))

    # Monate in Jahr und Monate
    if monat % 12 == 0:
        jahr = monat / 12
        restmonate = 0
    else:
        jahr = int(monat / 12)
        restmonate = monat % 12
        
    if restmonate == 0:
        jahr = jahr - 1
        restmonate = 12
        
    print("Jahre = ", jahr, "Restmonate = ", restmonate - 1)

    tk.Label(sum_frame, text="Jahre", bg="#FCFFB2").grid(sticky="w", row=2, column=3)
    tk.Label(sum_frame, text="Monate", bg="#FCFFB2").grid(sticky="w", row=3, column=3)
    tk.Label(sum_frame, text="Summe Zinsen", bg="#FCFFB2").grid(sticky="w", row=4, column=3)

    labeljahre = tk.Label(sum_frame, width='7', anchor="e", fg="blue")
    labeljahre.grid(row=2, column=1, padx='5', pady='5')
    labeljahre.config(text="{:.0f}".format(jahr))

    labelmonate = tk.Label(sum_frame, width='7', anchor="e")
    labelmonate.grid(row=3, column=1, padx='5', pady='5')
    labelmonate.config(text="{:.0f}".format(restmonate - 1))

    labelsummezinsen = tk.Label(sum_frame, width='7', anchor="e", fg="red")
    labelsummezinsen.grid(row=4, column=1, padx='5', pady='5')
    labelsummezinsen.config(text="{0:9.2f}".format(summezinsen))

    print(f"Summe Zinsen: {summezinsen:.2f}")


def enter_data():
    rest = float(darlehen_entry.get())
    zins1 = float(zinssatz_entry.get())
    rate = float(rate_entry.get())
    zbindung = float(zbindung_entry.get())
    zins2 = float(zins2_entry.get())
    sondertilgung = float(sondertilgung_entry.get())
       
    main(rest, zins1, rate, zbindung, zins2, sondertilgung)


window = tk.Tk()
window.title("Darlehen zurückzahlen")
window.geometry("900x500")
validation = (window.register(validate_number), '%P')


frame = tk.LabelFrame(text="Eingabe", width=400, height=400)
frame.pack(side=tk.LEFT, anchor="n", padx=5, pady=5)

eingabe_frame = tk.LabelFrame(frame, relief='raised', text="Eingabefelder")
eingabe_frame.grid(row=0, column=0, sticky="n", padx=5, pady=5)

sum_frame = tk.LabelFrame(eingabe_frame, text="Ergebnis zusammengefaßt", 
                width=200, height=200, relief='raised')
sum_frame.grid(row=10, column=0, sticky="news", padx=5, pady=5, columnspan=3)

darlehen_label = tk.Label(eingabe_frame, anchor="w", text="Darlehen", width=15, padx=15)
darlehen_label.grid(row=1, column=0)

zinssatz_label = tk.Label(eingabe_frame, anchor="w", text="Zinssatz", width=15)
zinssatz_label.grid(row=2, column=0)

rate_label = tk.Label(eingabe_frame, anchor="w", text="Rate", width=15)
rate_label.grid(row=3, column=0)

zbindung_label = tk.Label(eingabe_frame, anchor="w", text="Zinsbindung (Jahre)", width=15)
zbindung_label.grid(row=4, column=0)

zins2_label = tk.Label(eingabe_frame, anchor="w", text="Zinssatz nach Bindung", width=15)
zins2_label.grid(row=5, column=0)

sondertilgung_label = tk.Label(eingabe_frame, anchor="w", text="jährl. Sondertilgung", width=15)
sondertilgung_label.grid(row=6, column=0)

sondertilgung_entry = tk.DoubleVar()
sondertilgung_entry.insert = (0)


darlehen_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
zinssatz_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
rate_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
zbindung_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
zins2_entry = tk.Entry(eingabe_frame, width=6, validate="key", validatecommand=validation)
sondertilgung_entry = tk.Entry(eingabe_frame, textvariable=sondertilgung_entry, width=6, validate="key", validatecommand=validation)


darlehen_entry.grid(row=1, column=2)
zinssatz_entry.grid(row=2, column=2)
rate_entry.grid(row=3, column=2)
zbindung_entry.grid(row=4, column=2)
zins2_entry.grid(row=5, column=2)
sondertilgung_entry.grid(row=6, column=2)


sf = ScrolledFrame(width=700, height=800)
sf.pack()
inner_frame = sf.display_widget(tk.Frame)

sf.bind_arrow_keys(inner_frame)
sf.bind_scroll_wheel(inner_frame)
frame = tk.LabelFrame(inner_frame, text="Ergebnis")
frame.pack(side=tk.TOP, anchor="n", padx=5, pady=5)

ergebnis_frame = tk.LabelFrame(frame, text="Monate Ergebnis / Jahre",
                width=500, height=500, relief='raised')
ergebnis_frame.grid(row=1, column=0, sticky="ne", padx=5, pady=5)

button = tk.Button(eingabe_frame, text="rechne", bg="gray", fg="blue", command=enter_data)
button.grid(row=1, column=4, sticky="news", padx=20, pady=10)

window.mainloop()
Benutzeravatar
__blackjack__
User
Beiträge: 13684
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@gerdk: Das sieht insgesamt ziemlich schlimm aus. Das sind ein paar komische Sachen drin und das benutzt einen ganzen Haufen globaler Variablen statt das sauber in eine Klasse zu verpacken. Ausserdem ist die Programmlogik und die GUI vermischt. Die Berechnungen sollten extra sein und ohne den GUI-Code testbar sein. Denn bei der Berechnung scheint mir mindestens ein Fehler zu sein wenn man nicht mehr als ein Jahr hat.
„Incorrect documentation is often worse than no documentation.“ — Bertrand Meyer
gerdk
User
Beiträge: 12
Registriert: Freitag 17. Februar 2023, 19:52

Also:
ScrolledFrame wars nicht, habe statt dessen srolledtext verwendet.

Habe alles in eine Klasse gepackt.

Rechnung stimmt, vgl. Handelsblatt Tilgungsrechner

import tkinter as tk from tkinter impor ... mainloop()
gerdk
User
Beiträge: 12
Registriert: Freitag 17. Februar 2023, 19:52

irgendwas falsch angeklickt..

Code: Alles auswählen

import tkinter as tk
from tkinter import scrolledtext


class DarlehenRechner:
    def __init__(self, master):
        self.master = master
        self.master.title("Darlehen zurückzahlen")

        self.frame = tk.LabelFrame(master, text="Eingabe", width=400, height=400)
        self.frame.pack(side=tk.LEFT, anchor="n", padx=5, pady=5)

        self.eingabe_frame = tk.LabelFrame(self.frame, relief='raised', text="Eingabefelder")
        self.eingabe_frame.grid(row=0, column=0, sticky="n", padx=5, pady=5)

        self.sum_frame = tk.LabelFrame(self.eingabe_frame, text="Ergebnis zusammengefaßt", width=200, height=120, relief='raised')
        self.sum_frame.grid(row=6, column=0, sticky="news", padx=5, pady=5, columnspan=3)

        self.label_erstellen()
        self.ausgabe_text = scrolledtext.ScrolledText(master, width=50, height=41)
        self.ausgabe_text.pack(side=tk.RIGHT, anchor="ne", padx=10, pady=10)

    def label_erstellen(self):
        tk.Label(self.eingabe_frame, anchor="w", text="Darlehen:", width=15).grid(row=0, column=0, padx=5, pady=5)
        self.darlehen_entry = tk.Entry(self.eingabe_frame)
        self.darlehen_entry.grid(row=0, column=1, padx=5, pady=5)

        tk.Label(self.eingabe_frame, anchor="w", text="Zinssatz (%):", width=15).grid(row=1, column=0, padx=5, pady=5)
        self.zins_entry = tk.Entry(self.eingabe_frame)
        self.zins_entry.grid(row=1, column=1, padx=5, pady=5)

        tk.Label(self.eingabe_frame, anchor="w", text="Monatsrate:", width=15).grid(row=2, column=0, padx=5, pady=5)
        self.rate_entry = tk.Entry(self.eingabe_frame)
        self.rate_entry.grid(row=2, column=1, padx=5, pady=5)

        tk.Label(self.eingabe_frame, anchor="w", text="Zinsbindung(Jahre):", width=15).grid(row=3, column=0, padx=5, pady=5)
        self.zbindung_entry = tk.Entry(self.eingabe_frame)
        self.zbindung_entry.grid(row=3, column=1, padx=5, pady=5)

        tk.Label(self.eingabe_frame, anchor="w", text="Zinssatz nach Bindung:", width=15).grid(row=4, column=0, padx=5, pady=5)
        self.zins2_entry = tk.Entry(self.eingabe_frame)
        self.zins2_entry.grid(row=4, column=1, padx=5, pady=5)

        tk.Label(self.eingabe_frame, anchor="w", text="jährl. Sondertilgung:", width=15).grid(row=5, column=0, padx=5, pady=5)
        self.sondertilgung_entry = tk.Entry(self.eingabe_frame)
        self.sondertilgung_entry.grid(row=5, column=1, padx=5, pady=5)

        self.button = tk.Button(self.eingabe_frame, text="rechne", bg="gray", fg="blue", command=self.eingabe)
        self.button.grid(row=0, column=4, sticky="news", padx=20, pady=10)

    def main(self):
        darlehen = float(self.darlehen_entry.get())
        zinssatz = float(self.zins_entry.get())
        rate = float(self.rate_entry.get())
        zbindung = float(self.zbindung_entry.get())
        zins2 = float(self.zins2_entry.get())
        sondertilgung = float(self.sondertilgung_entry.get())

        self.ausgabe_text.delete(1.0, tk.END)
        self.ausgabe_text.insert(tk.END, "Tilgungsplan:\n")
        self.ausgabe_text.insert(tk.END, "Monat Zinssatz  Zinsen Tilgung SoTilgung     Rest\n")

        summezinsen = 0
        monat = 1

        while darlehen > 0:
            if monat <= zbindung * 12:
                zins = zinssatz
            else:
                zins = zins2

            zinsen = darlehen * zins / 100 / 12
            summezinsen = summezinsen + zinsen
            tilgung = rate - zinsen
            
            if tilgung > darlehen:
                tilgung = darlehen
            darlehen = darlehen - tilgung

            sonderz = 0
            if (monat % 12) == 0:
                sonderz = sondertilgung
                if sonderz > darlehen:
                    sonderz = darlehen
                darlehen = darlehen - sonderz
                
            self.ausgabe_text.insert(tk.END,f"{monat:2d}\t{zins:.2f}\t{zinsen:>6.2f}\t{tilgung:>6.2f}\t{sonderz:8.2f}\t{darlehen:>8.2f}\n")
            
            monat = monat + 1

        self.ausgabe_text.insert(tk.END, f"Summe Zinsen: {summezinsen:.2f}\n")

        # Jahre/Monate
        if monat % 12 == 0:
            jahr = monat / 12
            restmonate = 0
        else:
            jahr = int(monat / 12)
            restmonate = monat % 12
        if restmonate == 0:
            jahr = jahr - 1
            restmonate = 12

        tk.Label(self.sum_frame, text="Jahre", bg="#FCFFB2").grid(sticky="w", row=2, column=3)
        tk.Label(self.sum_frame, text="Monate", bg="#FCFFB2").grid(sticky="w", row=3, column=3)
        tk.Label(self.sum_frame, text="Summe Zinsen", bg="#FCFFB2").grid(sticky="w", row=4, column=3)

        labeljahre = tk.Label(self.sum_frame, width='7', anchor="e", fg="blue")
        labeljahre.grid(row=2, column=1, padx='5', pady='5')
        labeljahre.config(text="{:.0f}".format(jahr))

        labelmonate = tk.Label(self.sum_frame, width='7', anchor="e")
        labelmonate.grid(row=3, column=1, padx='5', pady='5')
        labelmonate.config(text="{:.0f}".format(restmonate - 1))

        labelsummezinsen = tk.Label(self.sum_frame, width='7', anchor="e", fg="red")
        labelsummezinsen.grid(row=4, column=1, padx='5', pady='5')
        labelsummezinsen.config(text="{0:9.2f}".format(summezinsen))

    def eingabe(self):
        try:
            self.main()
        except ValueError:
            self.ausgabe_text.delete(1.0, tk.END)
            self.ausgabe_text.insert(tk.END, "Bitte Eingaben prüfen.")


if __name__ == "__main__":
    window = tk.Tk()
    app = DarlehenRechner(window)
    window.mainloop()
Sirius3
User
Beiträge: 18078
Registriert: Sonntag 21. Oktober 2012, 17:20

Benutze keine kryptischen Abkürzungen, was ist eine zbindung? Was ist der Unterschied zwischen zinssatz und zins2?
Du vermischst die Geschäftslogik mit der GUI. Die Berechnung der Zinsen sollte also außerhalb der GUI stattfinden.
Das könnte ungefähr so aussehen:

Code: Alles auswählen

from itertools import repeat, chain

def berechne_tilgung(darlehen, zinsbindung_in_jahren, zinssatz_mit_bindung, zinssatz_ohne_bindung, rate, sondertilgung):
    summezinsen = 0
    ausgabe = []
    zinssaetze = chain(repeat(zinssatz_mit_bindung, 12 * zinsbindung_in_jahren), repeat(zinssatz_ohne_bindung))
    for monat, zins in enumerate(zinssaetze, 1):
        if darlehen <= 0:
            break

        zinsen = darlehen * zins / 100 / 12
        summezinsen += zinsen
        tilgung = min(darlehen, rate - zinsen)
        darlehen -= tilgung

        sonderzahlung = 0
        if monat % 12 == 0:
            sonderzahlung = min(darlehen, sondertilgung)
        darlehen -= sonderzahlung            
        ausgabe.append(f"{monat:2d}\t{zins:.2f}\t{zinsen:>6.2f}\t{tilgung:>6.2f}\t{sonderzahlung:8.2f}\t{darlehen:>8.2f}\n")
    ausgabe.append("Summe Zinsen: {summezinsen:.2f}\n")
    return ausgabe, summezinsen, monate
Die Umrechnung in Jahre und Restmonate ist kompliziert und uneinheitlich. Im einen Fall ist jahr ein float im anderen int.

Code: Alles auswählen

jahr, restmonate = divmod(monate, 12)
GUI-Elemente werden nur beim Initialisieren des Fensters erzeugt, nicht später. Das ist für den Nutzer verwirrend, außerdem werden beim Drücken des Kopfs immer wieder neue Label erzeugt, die nur die alten überdecken, sie aber nicht ersetzen.
gerdk
User
Beiträge: 12
Registriert: Freitag 17. Februar 2023, 19:52

Danke für die Hinweise,
divmod kannte ich nicht,
die while-Schleife habe ich (aus Bequemlichkeit) beibehalten,
einiges geändert.
Wg. treeview habe ich chatgpt gefragt (sorry), aber das Programm ist jetzt so, wie es haben wollte.

Code: Alles auswählen

import tkinter as tk
from tkinter import ttk

class DarlehenRechner:
    def __init__(self, master):
        self.master = master
        self.master.title("Darlehen zurückzahlen")

        # Schriftart für Ausgabe in treeview
        style = ttk.Style()
        style.configure("Treeview", font=("Courier", 12))

        self.frame = tk.LabelFrame(master)
        self.frame.pack(side=tk.LEFT, anchor="n", padx=5, pady=5)

        self.eingabe_frame = tk.LabelFrame(self.frame, relief='raised', text="Eingabefelder")
        self.eingabe_frame.grid(row=0, column=0, sticky="n", padx=5, pady=5)

        self.sum_frame = tk.LabelFrame(self.eingabe_frame, text="Ergebnis zusammengefaßt", width=200, height=116, relief='raised')
        self.sum_frame.grid(row=10, column=0, sticky="news", padx=5, pady=5, columnspan=3)

        self.erstelle_widgets()

        # Treeview für die Ausgabe
        self.tree_frame = tk.LabelFrame(master, relief='raised', text="Tilgungsplan", width=400, height=800)
        self.tree_frame.pack(side=tk.RIGHT, anchor="n", padx=5, pady=14, fill=tk.BOTH)

        self.tree = ttk.Treeview(self.tree_frame, columns=("Monat", "Zinssatz", "Zinsen", "Tilgung", "Sondertilgung", "Rest"), show='headings')
        self.setup_treeview()

    def setup_treeview(self):
        spalten = ("Monat", "Zinssatz", "Zinsen", "Tilgung", "Sondertilgung", "Rest")
        breiten = (60, 60, 70, 80, 80, 80)

        for index, (col, width) in enumerate(zip(spalten, breiten)):
            self.tree.heading(col, text=col)
            self.tree.column(index, width=width, anchor='ne')

        self.scrollbar = ttk.Scrollbar(self.tree_frame, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=self.scrollbar.set)

        self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    def erstelle_widgets(self):
        labels = ["Darlehen", "Zinssatz vor Bindung", "monatl. Rate", "Zinsbindung (Jahre)", "Zinssatz nach Bindung", "jährl. Sondertilgung"]
        self.entries = []

        for i, label in enumerate(labels):
            tk.Label(self.eingabe_frame, anchor="w", text=label, width=15).grid(row=i + 1, column=0)
            entry = tk.Entry(self.eingabe_frame, width=6)
            entry.grid(row=i + 1, column=2)
            self.entries.append(entry)

        self.button = tk.Button(self.eingabe_frame, text="rechne", bg="gray", fg="blue", command=self.berechne_tilgung)
        self.button.grid(row=1, column=4, sticky="news", padx=5, pady=5)

    def berechne_tilgung(self):
        try:
            darlehen = float(self.entries[0].get())
            zinssatz = float(self.entries[1].get())
            rate = float(self.entries[2].get())
            zinsbindung = float(self.entries[3].get())
            zinssatz_nach_bindung = float(self.entries[4].get())
            sondertilgung = float(self.entries[5].get())
        except ValueError:
            self.show_error_message()
            return

        # Treeview leeren
        for row in self.tree.get_children():
            self.tree.delete(row)

        summezinsen = 0
        monat = 1
        rest = darlehen

        while rest > 0:
            zins = zinssatz if monat <= zinsbindung * 12 else zinssatz_nach_bindung
            zinsen = rest * zins / 1200
            summezinsen += zinsen
            
            tilgung = rate - zinsen
            if tilgung > rest:
                tilgung = rest
            rest -= tilgung

            sonderz = sondertilgung if monat % 12 == 0 else 0                       
            if sonderz > rest:
                sonderz = rest
            rest -= sonderz

            # Daten in die Treeview einfügen
            self.tree.insert("", "end", values=(f"{monat:>4d}", f"{zins:>7.2f}", f"{zinsen:>8.2f}", f"{tilgung:>9.2f}", f"{sonderz:>10.2f}", f"{rest:>10.2f}"))
            monat += 1

        #self.tree.insert("", "end", values=("", "", "========="))
        #self.tree.insert("", "end", values=("", "", f"{summezinsen:>7.2f}"))

        # Summe Zinsen ausgeben
        jahr, restmonate = divmod(monat - 1, 12)
        self.ausgabe_summen(jahr, restmonate, summezinsen)

    def ausgabe_summen(self, jahr, restmonate, summezinsen):
        tk.Label(self.sum_frame, text="Jahre", bg="#FCFFB2").grid(sticky="w", row=2, column=3)
        tk.Label(self.sum_frame, text="Monate", bg="#FCFFB2").grid(sticky="w", row=3, column=3)
        tk.Label(self.sum_frame, text="Summe Zinsen", bg="#FCFFB2").grid(sticky="w", row=4, column=3)

        tk.Label(self.sum_frame, width='7', anchor="e", fg="blue", text=f"{jahr:.0f}").grid(row=2, column=1, padx='5', pady='5')
        tk.Label(self.sum_frame, width='7', anchor="e", text=f"{restmonate:.0f}").grid(row=3, column=1, padx='5', pady='5')
        tk.Label(self.sum_frame, width='7', anchor="e", fg="red", text=f"{summezinsen:9.2f}").grid(row=4, column=1, padx='5', pady='5')

    def show_error_message(self):
        for row in self.tree.get_children():
            self.tree.delete(row)
        self.tree.insert("", "end", tags=('fg', 'bg'),  values=("Eingabe", "prüfen!")) 
        self.tree.tag_configure('fg', foreground='red')


if __name__ == "__main__":
    window = tk.Tk()
    app = DarlehenRechner(window)
    window.mainloop()
Antworten