Tkinter Anzeige verschiebt sich nach unten

Fragen zu Tkinter.
Antworten
techpirat
User
Beiträge: 8
Registriert: Donnerstag 10. Februar 2022, 21:59

Hallo zusammen,
Ich habe mir eine kleines Programm gebaut mit dem ich csv Dateien Auswerte und im Fenster das Ergebnis anzeigen lasse. So weit so gut.
Die Anzeige soll über zwei Fenster gehen damit ich später, je Fenster, eine andere Ausgaben anzeigen lassen kann.
Gehe ich von tab1 auf tab2 ist alles gut gehe ich aber zurück wieder auf tab1 wird oben eine anscheint Zeile /Abstand hinzugefügt und alles rutscht nach unten.
Anbei Bilder und Code mit der Bitte um Hilfe :)

Bild
Bild
Bild
soll natürlich eingefügter Bereich heißen :wink:

Code: Alles auswählen

import os
import locale
import csv
from time import sleep
from logging import root
import tkinter as tk
from tkinter import BOTTOM, Label, ttk
from tkinter import font
from PIL import Image, ImageTk
root = tk.Tk()
root.minsize(width=800, height=500)
#Größe lässt sich nicht ändern true ist auch möglich für eine Angabe
root.resizable(width=True, height=True)
root.minsize(width=450, height=250)
#root.maxsize(width=800, height=400)
root.title("Wie ist der Umsatz?")
image = Image.open("penguin-161356.png").resize((150,150))
photo = ImageTk.PhotoImage(image)
label2 = ttk.Label(root,image=photo, compound="center")
label2.pack(side="bottom")  
def tab1():
    #Zeichensatz festlegen
    locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
    os.system('python /Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/fehler_beseitigen.py')
    sleep(5)
    os.system('python /Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/csv_sortieren_letzten30.py')
    os.system('python /Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/csv_sortieren_heute.py')
    os.system('python /Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/csv_sortieren_gestern.py')
    rohertrag_gesamt = 0.0
    vk_gesamt = 0.0
    ek_gesamt = 0.0
    bvk_gesamt = 0.0
    anzahl_gesamt = 0
    #################################### heute #######################################################
    #öffne die neue Datei
    with open('/Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/output_heute.csv') as csvdatei:
        csv_reader = csv.reader(csvdatei, delimiter=',')
        _ = next(csv_reader)
        for zeilennummer, row in enumerate(csv_reader, 1):
    #in welcher Spalte wird gesucht        
            brutto_vk = locale.atof(row[5])
            netto_vk = locale.atof(row[7])
            netto_ek = locale.atof(row[14].split('~', 1)[1])
            anzahl = locale.atof(row[18])
    #berechnen das Rohertrags
            rohertrag = netto_vk - netto_ek
    #summen
            bsumme_vk = brutto_vk
            summe_vk = netto_vk
            summe_ek = netto_ek
            summe_anzahl = anzahl
    #summen Berechnung
            bvk_gesamt = bvk_gesamt + bsumme_vk
            vk_gesamt = vk_gesamt + summe_vk
            ek_gesamt = ek_gesamt + summe_ek
            anzahl_gesamt = anzahl_gesamt + anzahl
    #berechnen das Rohertrag in %
            ertrag_prozent = 100-ek_gesamt/(vk_gesamt/100)
            rohertrag_gesamt = rohertrag_gesamt + rohertrag
    #gefundene Werte anzeigen EK Preis
    #Auflistung des Ergebniss
        global str_1h, str_2h, str_4h, str_4h, str_5h,str_6h, str_7h
        str_1h = (f'Verkauf brutto: '+ locale.format_string('%.2f', bvk_gesamt, True)+ f"€")
        str_2h = (f'Verkauf netto: '+ locale.format_string('%.2f', vk_gesamt, True)+ f"€")
        str_3h = (f'Einkauf netto: '+ locale.format_string('%.2f', ek_gesamt, True)+ f"€")
        str_4h = (f'Rohertrag: '+ locale.format_string('%.2f', rohertrag_gesamt, True)+ f"€")
        str_5h = (f'Ertrag in %: '+ locale.format_string('%.2f', ertrag_prozent, True))
        str_6h = (f'Verkäufe: {zeilennummer}')
        str_7h = (f'Anzahl: '+ locale.format_string('%.0f', anzahl_gesamt, True))
#################################### import Ende  #######################################################
    image = Image.open("penguin-161356.png").resize((150,150))
    photo = ImageTk.PhotoImage(image)
   
    ueberschrift_heute = ("Umsatz von heute:")
    ueberschrift_gestern = ("Umsatz von gestern:")
    ueberschrift_30 = ("Umsatz der letzten 30 Tage:")
    #StringVar für Text, IntVar für ganze Zahlen, DoubleVar für Komma Zahlen, BooleanVar für z.B. True oder Falsw
    text_1 = tk.StringVar()
    text_1.set(ueberschrift_heute +"\n"+ str_1h + "\n"+ str_2h+ "\n"+ str_3h+ "\n"+ str_4h+ "\n"+ str_5h+ "\n"+ str_6h) 
    #widjet erstellen mit der Variable label
    label1 = label1 = tk.Label(root, textvariable=text_1, font="Courie, 18",justify="left",padx="10")
    label1.pack(side="left", padx=5, pady=10) 

    #label mit Bild und Text compound ist zur plazierung
    #label4 = ttk.Label(root, text="das ist ein Bild", image=photo, compound="center")
    label8 = ttk.Label(root,image=photo, compound="center")
    label8.pack(side="top")
    #################################### zweite Fenster Start  ####################################################### 
    def tab2 ():
        label5.destroy()
        button5.destroy()
        label6=Label(root,text='Das zweite Fenster', font=('Times_New_Roman'))
        label6.pack()
        image = Image.open("penguin-161356.png").resize((150,150))
        photo = ImageTk.PhotoImage(image)
        label8 = ttk.Label(root,image=photo, compound="center")
        label8.pack(side="top") 
    #################################### zweite Fenster Ende  #######################################################
        def back():
            label6.destroy()
            button6.destroy()
            label1.destroy()
            tab1()
        button6=ttk.Button(root, text='Back', command=back)
        button6.pack(side=BOTTOM)
        #root.after(6000, back)
        #################################### zurück Fenster Ende  #######################################################
    label5=Label(root,text='Das erste Fenster', font=('Times_New_Roman'))
    label5.pack()
    button5=ttk.Button(root, text='Next',command=tab2)
    button5.pack(side=BOTTOM)
    #root.after(6000, tab2)
tab1()
root.mainloop()
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Man benutzt kein `global`, und in GUIs auch kein `sleep`. Man verschachtelt keine Funktionen, erst recht nicht bis zur dritten Ebene.
`os.system` benutzt man nicht. Normalerweise würde man hier subprocess.run empfehlen, da es sich aber um Python-Programme handelt, ist der richtige Weg, die Module zu importieren und die Funktionen darin direkt aufzurufen.
Die drei `csv_sortiere`-Programme lassen befürchten, dass sie alle drei das selbe machen, bis auf einen Parameter, der den Zeitraum bestimmt.
Statt hier mit Lokalen zu arbeiten, würde ich Pandas empfehlen, damit sind die Rechungen auch Einzeiler.
Die Strings 1Stunde bis 7Stunden sind sehr schlecht benannt, auch bei anderen Variablennamen sollte man keine Abkürzungen benutzen. Warum bvk statt brutto_verkauf?
Du hast Format-Strings noch nicht verstanden, und solltest Dir das Kapitel in der Dokumentation nochmal durchlesen.

Und zum eigentlichen Problem: man verändert keine GUI-Fenster dynamisch. Man baut einmal das Fenster auf, benutzt Frames um zusammengehörende Dinge zusammenzufassen und schiebt dann entweder das eine oder das andere Tab in den Vordergrund.
Für GUI-Programme braucht man zwingend Klassendefinitionen, um den Zustand der Fenster sauber zu speichern und zwischen verschiedenen Methoden herumzureichen.
techpirat
User
Beiträge: 8
Registriert: Donnerstag 10. Februar 2022, 21:59

Danke für die ausführlich Antwort und die wertvollen Tipps . Dann versuche ich das mal umzubauen.
techpirat
User
Beiträge: 8
Registriert: Donnerstag 10. Februar 2022, 21:59

Sirius3 hat geschrieben: Samstag 19. März 2022, 22:36 Man benutzt kein `global`, und in GUIs auch kein `sleep`. Man verschachtelt keine Funktionen, erst recht nicht bis zur dritten Ebene.
`os.system` benutzt man nicht. Normalerweise würde man hier subprocess.run empfehlen, da es sich aber um Python-Programme handelt, ist der richtige Weg, die Module zu importieren und die Funktionen darin direkt aufzurufen.
Die drei `csv_sortiere`-Programme lassen befürchten, dass sie alle drei das selbe machen, bis auf einen Parameter, der den Zeitraum bestimmt.
Statt hier mit Lokalen zu arbeiten, würde ich Pandas empfehlen, damit sind die Rechungen auch Einzeiler.
Die Strings 1Stunde bis 7Stunden sind sehr schlecht benannt, auch bei anderen Variablennamen sollte man keine Abkürzungen benutzen. Warum bvk statt brutto_verkauf?
Du hast Format-Strings noch nicht verstanden, und solltest Dir das Kapitel in der Dokumentation nochmal durchlesen.

Und zum eigentlichen Problem: man verändert keine GUI-Fenster dynamisch. Man baut einmal das Fenster auf, benutzt Frames um zusammengehörende Dinge zusammenzufassen und schiebt dann entweder das eine oder das andere Tab in den Vordergrund.
Für GUI-Programme braucht man zwingend Klassendefinitionen, um den Zustand der Fenster sauber zu speichern und zwischen verschiedenen Methoden herumzureichen.
Ich habe jetzt meine Fähigkeiten entsprechend den Code nach deinen Vorgaben angepasst :)
global und sleep ist raus war nur eine Krücke
das Verschachteln habe ich aufgehoben? Habe ich?
os habe ich gegen Import ersetzt
Pandas schaue ich mir an habe ich auch schon mir rum experimentiert
Die Benennung werde ich noch anpassen
Frames habe ich erstellt

Hier mein aktuelle Code:

Code: Alles auswählen

import locale
import csv
from logging import root
import tkinter as tk
from tkinter import Label, ttk
from PIL import Image, ImageTk
from tkinter import Frame, Button
#Zeichensatz festlegen
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')

def aktualisieren():
        label1.destroy()
        print("Aktualisieren")
        
        
root = tk.Tk()
frame1 = Frame(root)
frame2 = Frame(root)
root.title("tkinter frame")

#Zeichensatz festlegen
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
import fehler_beseitigen
import csv_sortieren_heute
rohertrag_gesamt = 0.0
vk_gesamt = 0.0
ek_gesamt = 0.0
bvk_gesamt = 0.0
anzahl_gesamt = 0
#################################### heute #######################################################
#öffne die neue Datei
with open('/Users/joerg/Documents/python/Rohertrag/rohertrag_fenster/output_heute.csv') as csvdatei:
    csv_reader = csv.reader(csvdatei, delimiter=',')
    _ = next(csv_reader)
    for zeilennummer, row in enumerate(csv_reader, 1):
    #in welcher Spalte wird gesucht        
        brutto_vk = locale.atof(row[5])
        netto_vk = locale.atof(row[7])
        netto_ek = locale.atof(row[14].split('~', 1)[1])
        anzahl = locale.atof(row[18])
        #berechnen das Rohertrags
        rohertrag = netto_vk - netto_ek
        #summen
        bsumme_vk = brutto_vk
        summe_vk = netto_vk
        summe_ek = netto_ek
        summe_anzahl = anzahl
        #summen Berechnung
        bvk_gesamt = bvk_gesamt + bsumme_vk
        vk_gesamt = vk_gesamt + summe_vk
        ek_gesamt = ek_gesamt + summe_ek
        anzahl_gesamt = anzahl_gesamt + anzahl
        #berechnen das Rohertrag in %
        ertrag_prozent = 100-ek_gesamt/(vk_gesamt/100)
        rohertrag_gesamt = rohertrag_gesamt + rohertrag
        #gefundene Werte anzeigen EK Preis
        #Auflistung des Ergebniss
        str_1h = (f'Verkauf brutto: '+ locale.format_string('%.2f', bvk_gesamt, True)+ f"€")
        str_2h = (f'Verkauf netto: '+ locale.format_string('%.2f', vk_gesamt, True)+ f"€")
        str_3h = (f'Einkauf netto: '+ locale.format_string('%.2f', ek_gesamt, True)+ f"€")
        str_4h = (f'Rohertrag: '+ locale.format_string('%.2f', rohertrag_gesamt, True)+ f"€")
        str_5h = (f'Ertrag in %: '+ locale.format_string('%.2f', ertrag_prozent, True))
        str_6h = (f'Verkäufe: {zeilennummer}')
        str_7h = (f'Anzahl: '+ locale.format_string('%.0f', anzahl_gesamt, True))
#################################### import Ende  #######################################################
image = Image.open("penguin-161356.png").resize((150,150))
photo = ImageTk.PhotoImage(image)
ueberschrift_heute = ("Umsatz von heute:")
ueberschrift_gestern = ("Umsatz von gestern:")
ueberschrift_30 = ("Umsatz der letzten 30 Tage:")
#StringVar für Text, IntVar für ganze Zahlen, DoubleVar für Komma Zahlen, BooleanVar für z.B. True oder Falsw
text_1 = tk.StringVar()
text_1.set(ueberschrift_heute +"\n"+ str_1h + "\n"+ str_2h+ "\n"+ str_3h+ "\n"+ str_4h+ "\n"+ str_5h+ "\n"+ str_6h) 
#widjet erstellen mit der Variable label
label1 = label1 = tk.Label(root, textvariable=text_1, font="Courie, 18",justify="left",padx="10")
label1.pack(side="left", padx=5, pady=10) 

#label mit Bild und Text compound ist zur plazierung
label8 = ttk.Label(frame2,image=photo, compound="center")
label8.pack(side="top")

label= Label(frame1,text="Label",justify="left")
label.pack(side="left")

hi_there = Button(frame2,text="Aktualisieren",command=aktualisieren)
hi_there.pack()

frame1.pack(padx=10,pady=10)
frame2.pack(padx=10,pady=10)
root.mainloop()
Mir fehlt immer noch das Verständnis wie ich die Anzeige aktualisiert bekomme. Für mein Verständnis destroy ich das Angezeigte und gehe zurück auf Anfang. Aber das gelingt mir nicht

Über weitere Hilfe würde ich mich freien :)
Antworten