Blödes Fenster... :)

Fragen zu Tkinter.
Antworten
DMD-OL
User
Beiträge: 168
Registriert: Samstag 26. Dezember 2015, 16:21
Wohnort: Oldenburg (Oldenburg)

Mittwoch 4. Mai 2016, 13:39

Hi
ich habe einen code geschrieben, der mir die einzelen daten nacheinander in verschiedenen fenstern tabellarisch (mit scrollbar) ausgeben soll.
die fenster sollen hintereinander ausgegeben werden:

Code: Alles auswählen

from Tkinter import *
import Tkinter
from collections import defaultdict

tabelle_LIST = [['Mi, 06.04.2016', u'aaa', u'---', u'---', 1, 2, 3, 4], ['Di, 12.04.2016', u'aaa', u'14:59', u'17:06', 1, 2, 3, 4], ['Fr, 29.04.2016', u'bbb', u'---', u'---', 1, 2, 3, 4]]

DATUM_Monat = 'April 2016'
bauVor_Nummer = 0
bauVor_Name = 'Hoffmann/Winkler'

hauptfenster = Tkinter.Tk()
hauptfenster.geometry('300x200+285+180')

def bv_Uebersicht(bauVor_Nummer,DATUM_Monat,tabelle_LIST):

    summe_Ist = []
    summe_Soll = []
    summe_Bezahlt = []
    summe_Ueber = []
    bauvor_List = []
    for kalsla in tabelle_LIST:
        item_0 =  kalsla[0]
        item_1 = kalsla[1]
        item_2 = kalsla[2]
        item_3 = kalsla[3]
        item_4 = kalsla[4]
        item_5 = kalsla[5]
        item_6 = kalsla[6]
        item_7 = kalsla[7]
        oransk = [item_0,item_1,item_4,item_5,item_6,item_7]
        bauvor_List.append(oransk)

    minDopp = defaultdict(list)
    for eintragung in bauvor_List:
        minDopp[eintragung[1]].append(eintragung)
    x_sauber = []
    for eintraeger in minDopp.keys():
        x_sauber.append(eintraeger)
    bauvorList = []
    for eintraeger in minDopp.values():
        for omar in eintraeger:
            dortog = omar[0]
            nimen = omar[1]
            dauER = omar[2]
            pauSE = omar[3]
            haLB = omar[4]
            uebER = omar[5]
            kossen = [dortog,nimen,dauER,pauSE,haLB,uebER]
            bauvorList.append(kossen)

    listense = []
    merker = []
    merkerName = []
    indexes = len(x_sauber)-1
    for rowter, name in enumerate(x_sauber):
        del listense[:]
        del summe_Ist[:]
        del summe_Soll[:]
        del summe_Bezahlt[:]
        del summe_Ueber[:]
        for y in bauvorList:
            if name == y[1]:
                driTag =  y[0]
                vornachName = y[1]
                arbDauer = y[2]
                arbPause = y[3]
                arbHalb =  y[4]
                arbUeber = y[5]
                trarer = [driTag,arbDauer,arbPause,arbHalb,arbUeber]
                listense.append(trarer)

        def data():
            for row, items in enumerate(listense):
                for column, item in enumerate(items):
                    reihe = Tkinter.Label(frame, text=(item),font=('Arial', 9, 'bold'), width=18, relief="raised", bg='#cdc8b1', fg="#000000000", justify='center').grid(row=row, column=column+7)
        def myfunction(event):
            canvas.configure(scrollregion=canvas.bbox("all"),width=665,height=200)

        fenster_1 = Tkinter.Tk()
        fenster_1.wm_geometry("700x580+200+50")
        fenster_1.attributes("-topmost", True)

        for krimm in merkerName:
            label_120 = Tkinter.Label(fenster_1, text=(str(krimm)), font=('Arial', 11, 'bold'), height=3, width=40,  fg="#000000000", justify='left')
            label_120.place(x=50,y=220)
        l_uet12 = Tkinter.Label(fenster_1,text=('DATUM'),font=('Arial', 9, 'bold'),height=2,width=18, relief="ridge",  bg="#ddddddddd", fg="#000000000", justify='center')
        l_uet12.place(x=14,y=290)
        l_uet16 = Tkinter.Label(fenster_1,text=('FELD 1'),font=('Arial', 9, 'bold'),height=2,width=19, relief="ridge",  bg="#ddddddddd", fg="#000000000", justify='center')
        l_uet16.place(x=144,y=290)
        l_uet17 = Tkinter.Label(fenster_1,text=('FELD 2'),font=('Arial', 9, 'bold'),height=2,width=18, relief="ridge",  bg="#ddddddddd", fg="#000000000", justify='center')
        l_uet17.place(x=276,y=290)
        l_uet18 = Tkinter.Label(fenster_1,text=('FELD 3'),font=('Arial', 9, 'bold'),height=2,width=18, relief="ridge",  bg="#ddddddddd", fg="#000000000", justify='center')
        l_uet18.place(x=406,y=290)
        l_uet19 = Tkinter.Label(fenster_1,text=('FELD 4'),font=('Arial', 9, 'bold'),height=2,width=19, relief="ridge",  bg="#ddddddddd", fg="#000000000", justify='center')
        l_uet19.place(x=536,y=290)
        myframe=Frame(fenster_1,relief=GROOVE,width=50,height=50,bd=1)
        myframe.place(x=10,y=330)
        canvas=Canvas(myframe)
        frame=Frame(canvas)
        myscrollbar=Scrollbar(myframe,orient="vertical",command=canvas.yview)
        canvas.configure(yscrollcommand=myscrollbar.set)
        myscrollbar.pack(side="right",fill="y")
        canvas.pack(side="left")
        canvas.create_window((50,50),window=frame,anchor='nw')
        frame.bind("<Configure>",myfunction)
        data()
        Button(fenster_1,text='Schliessen' if rowter == indexes else 'Weiter',width=12,command=fenster_1.destroy,).place(x=500,y=235)
        merker.append(fenster_1)

b_uet20 = Tkinter.Button(hauptfenster, text = 'Bestaetigen', width=12, relief="raised", fg="#000000000", justify='center', command=lambda:bv_Uebersicht(bauVor_Nummer,DATUM_Monat,tabelle_LIST))
b_uet20.place(x=150,y=100)

hauptfenster.mainloop()
warum ist die scrollbar im ersten fenster immer falsch angezeigt???
ich hab schon alles versucht, versteh aber einfach nicht, was ich falsch mache.
bitte hilfe :)
BlackJack

Sonntag 8. Mai 2016, 18:53

@DMD-OL: Was auf jeden Fall falsch ist, sind mehrere Exemplare von `Tk` zur selben Zeit. Davon darf es immer nur ein Exemplar geben. Zusätzliche Fenster kann man mit `Toplevel` erstellen.

Ansonsten wehrt sich Python vielleicht auch einfach nur gegen diesen schrecklichen Quelltext. :twisted:

Was vielleicht auch der Grund ist, warum hier bisher noch niemand geantwortet hatte: Durch den Quelltext mag man sich nicht quälen. Sternchen-Import, schlechte Namen, die zudem nicht dem Style Guide for Python Code entsprechen, Code und Variablen auf Modulebene, verschachtelte Funktionen, viele Variablen die definiert, dann aber nicht verwendet werden, zu lange Zeilen, Grundatentypen in Namen kodiert, absolutes positionieren mit `place()` statt Layouts die automatisch für die Anordnung der Widgets sorgen, …

In der Funktion `bv_Uebersicht()` gibt es fast 60 lokale Namen. Das ist einfach mal ganz krass zu viel. Die Funktion ist auch deutlich zu lang.

``del sequence[:]`` ist ungewöhnlich weil man das nur machen muss, wenn das Listenobjekt irgendwo anders referenziert wird, und sich diese Änderung dort auch auswirken muss. Das ist aber etwas was man vermeiden sollte, weil es unübersichtliche Abhängigkeiten schafft. Wenn man eine leere Liste braucht, sollte man einfach eine neue, leere Liste erstellen.

Diese ganze Umpackerei mit dem `defaultdict` und den verschiedenen Listen ist extrem unübersichtlich. Dass das `defaultdict` dann wieder in zwei Listen umgewandelt wird um dann später im Code in der Werteliste linear genau die Sachen wieder zu suchen die im `defaultdict` ja mal aufgeschlüsselt waren, ist komplett sinnfrei. Das `defaultdict` wird letztendlich überhaupt nicht verwendet.

`data()` ist als Funktion überflüssig. Den Funktionskörper hätte man an der Stelle auch einfach statt des Aufrufs schreiben können.

Das Problem mit der Canvas-Grösse ist das in der Schleife sowohl die Rückruffunktion für das Configure-Ereignis als auch das Canvas-Objekt was die Rückruffunktion verwendet, neu definiert wird. Und diese Funktion löst den Namen `canvas` nicht auf wenn sie definiert wird, sondern erst wenn sie aufgerufen wird. Dann ist aber immer das letzte Canvas an den diesen Namen gebunden, also wirken sich alle Rückruffunktionen auch nur auf dieses aus. Lösung wäre auch das Canvas als Argument entgegenzunehmen und mit `functools.partial()` an das jeweilige Canvas-Objekt zu binden. Oder man bricht diese gruselige Monsterfunktion auf und fängt an das ordentlich objektorientiert zu lösen.
Antworten