Combobox soll inhalt einer anderen Combobox "beeinflussen"

Fragen zu Tkinter.
Antworten
Apex
User
Beiträge: 8
Registriert: Montag 10. April 2017, 12:50

Hallo

ich versuche einen Riesen Stapel von PDF Dateien umzubenennen und umzuspeichern. Es handelt sich um alte Klausuren die mir als PDF vorliegen und nun habe ich angefangen mir ein Python Tool zu schreiben.
Ich nutze dass projekt um die Sprache zu lernen und bin jetzt an einem Punkt wo es läuft aber noch stark verbesserungswürdig ist.

Zu meiner Frage. Wie kann ich es machen dass eine Auswahl in einer Combobox den Inhalt einer anderen Combobox einstellt und diese Auswahl dann wieder eine Andere Combobox anpasst.

Die dazugehörig CSV kann ich bei bedarf auch hochladen.

Hier mein Scipt:

Code: Alles auswählen

# -*- coding: utf-8 -*-
from tkinter import Tk,Button,Frame,Label,filedialog, ttk, Menu, Toplevel, Entry
import os as os
import tkinter as tkinter
import csv as csv
#To Do
"""
-Studium Generale rein (Liste + CSV), zweites Dropdown
-If-BA/MA Abfragen zu Studiengängen
-Main Menü (Datei,Optionen,Info/About) erstellen
-Öffnen der Ursprungsdatei (Vorschau)
"""
class Application(Frame):
    #Design des Fensters und deren Darstellung

    def __init__(self, master=None):
        Frame.__init__(self, master)        
       
        self.lst_abschluss=[]        
        #print("Leer: ",self.lst_abschluss)        
        self.lst_studiengang=[]
        self.lst_modul=[]
        self.lst_semester=[]
        self.lst_dozent=[]
        self.lst_przr=[]
        self.lst_version=[]
        self.lst_note=[]
        self.total_content=[]
        with open('LOUIS-Beuth-Renamer.csv','r',newline='')as csvfile:
            for row in csv.reader(csvfile):
                    self.total_content.append(row)
        self.lst_abschluss=self.total_content[0]
        self.lst_abschluss_mod=self.total_content[0]        
        self.lst_studiengang_BA=self.total_content[1]
        self.lst_studiengang_MA=self.total_content[2]
        
        #Modulnamen weiter anpassen
        self.lst_module_BA_BauIng=self.total_content[3]
        self.lst_module_BA_UmweltIng=self.total_content[4]
        self.lst_module_BA_WiIng=self.total_content[5]
        self.lst_module_BA_GeoInfo=self.total_content[6]
        self.lst_module_MA_WiIng=self.total_content[7]
        self.lst_module_MA_BauIng=self.total_content[8]
        self.lst_module_MA_GeoInfo=self.total_content[9]
        self.lst_module_MA_UmweltIng=self.total_content[10]
        self.lst_semester=self.total_content[11]
        self.lst_dozent=self.total_content[12]
        self.lst_przr=self.total_content[13]
        self.lst_version=self.total_content[14]
        self.lst_note=self.total_content[15]
        #print(self.lst_abschluss)
        #print(self.lst_studiengang)
                             

        self.var_abschluss = tkinter.StringVar()
        self.var_abschluss.set("unbekannt")    

        self.var_studiengang = tkinter.StringVar()
        self.var_studiengang.set("unbekannt")        
        
        self.var_modul = tkinter.StringVar()
        self.var_modul.set("unbekannt")        

        self.var_semester = tkinter.StringVar()
        self.var_semester.set("unbekannt")        

        self.var_dozent = tkinter.StringVar()
        self.var_dozent.set("unbekannt")        

        self.var_przr = tkinter.StringVar()
        self.var_przr.set("unbekannt")        

        self.var_version = tkinter.StringVar()
        self.var_version.set("unbekannt")        

        self.var_note = tkinter.StringVar()
        self.var_note.set("unbekannt")        
        self.create_widgets()
        self.drop_refresh()
        self.mainmenu()
    
    #Create
    def create_widgets(self):
        self.abschluss_l = Label(root,text="Abschluss:  ")
        self.abschluss_l.grid(row=0,column=0,sticky='w')
        self.studiengang_l = Label(root,text="Studiengang:  ")
        self.studiengang_l.grid(row=1,column=0,sticky='w')
        self.modul_l = Label(root,text="Modulname:  ")
        self.modul_l.grid(row=2,column=0,sticky='w')
        self.semester_l = Label(root,text="Semester:  ")
        self.semester_l.grid(row=3,column=0,sticky='w')
        self.dozent_l = Label(root,text="Dozent:  ")
        self.dozent_l.grid(row=4,column=0,sticky='w')        
        self.przr_l = Label(root,text="Prüfungszeitraum:  ")
        self.przr_l.grid(row=5,column=0,sticky='w')        
        self.version_l = Label(root,text="Version:  ")
        self.version_l.grid(row=6,column=0,sticky='w')        
        self.note_l = Label(root,text="Note:  ")
        self.note_l.grid(row=7,column=0,sticky='w')

        self.select_button = Button(root,text="Datei",command=self.datei_waehlen)
        self.select_button.grid(row=8,column=0,sticky='w')  
        self.save_button = Button(root,text="Speichern",command=self.save_file)
        self.save_button.grid(row=8,column=0,sticky='e')

        self.vorschau_label = Label(root,text='')
        self.vorschau_label.grid(row=11,columnspan=1000)
        self.datei_label = Label(root,text='Datei:  ')
        self.datei_label.grid(row=9,column=0,sticky='w')
        self.datei_gewaehlt = Label(root,text='')
        self.datei_gewaehlt.grid(row=9,column=1)
        
        self.vorschau_button = Button(root,text="Vorschau des Dateinamen ",command=self.dateiname_vorschau)
        self.vorschau_button.grid(row=10,column=0)
        
    def drop_refresh(self):                             
        self.drop_abschluss = ttk.Combobox(root,textvariable=self.var_abschluss,values=self.lst_abschluss)
        self.drop_abschluss.grid(row=0,column=1)
        self.drop_studiengang = ttk.Combobox(root,textvariable=self.var_studiengang,values=self.lst_studiengang_BA)        
        #self.drop_studiengang = ttk.Combobox(root,textvariable=self.var_studiengang,values=self.lst_studiengang)
        self.drop_studiengang.grid(row=1,column=1)
        self.drop_modul = ttk.Combobox(root,textvariable=self.var_modul,values=self.lst_module_BA_BauIng)
        #self.drop_modul = ttk.Combobox(root,textvariable=self.var_modul,values=self.lst_modul)
        self.drop_modul.grid(row=2,column=1)
        self.drop_semester = ttk.Combobox(root,textvariable=self.var_semester,values=self.lst_semester)
        self.drop_semester.grid(row=3,column=1)
        self.drop_dozent = ttk.Combobox(root,textvariable=self.var_dozent,values=self.lst_dozent)
        self.drop_dozent.grid(row=4,column=1)
        self.drop_przr = ttk.Combobox(root,textvariable=self.var_przr,values=self.lst_przr)
        self.drop_przr.grid(row=5,column=1)
        self.drop_version = ttk.Combobox(root,textvariable=self.var_version,values=self.lst_version)
        self.drop_version.grid(row=6,column=1)
        self.drop_note = ttk.Combobox(root,textvariable=self.var_note,values=self.lst_note)
        self.drop_note.grid(row=7,column=1)
        
            
        
    def mainmenu(self):
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label="Neu", command=self.donothing)
        filemenu.add_command(label="Öffnen", command=self.donothing)
        filemenu.add_command(label="Speichern", command=self.donothing)
        filemenu.add_command(label="Speichern unter...", command=self.donothing)
        filemenu.add_command(label="Schließen", command=self.donothing)      
        filemenu.add_separator()      
        filemenu.add_command(label="Beenden", command=self.close_app)    
        menubar.add_cascade(label="Datei", menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        editmenu.add_command(label="Dozent hinzufügen", command=self.add_dozent)
        editmenu.add_command(label="Modul hinzufügen", command=self.add_modul)
        editmenu.add_separator() 
        editmenu.add_command(label="Dozent entfernen", command=self.del_dozent)
        editmenu.add_command(label="Modul entfernen", command=self.del_modul)             
        menubar.add_cascade(label="Bearbeiten", menu=editmenu)

        helpmenu = Menu(menubar, tearoff=0)
        helpmenu.add_command(label="Help Index", command=self.donothing)
        helpmenu.add_command(label="About...", command=self.about)
        menubar.add_cascade(label="About", menu=helpmenu)
    
    def close_app(self):
        root.destroy()
        
    def donothing(self):
        button = Button(root, text="Do nothing button")
        button.pack()
    
    def datei_waehlen(self):
        self.filepath=filedialog.askopenfilename()
        self.filename=os.path.basename(self.filepath)
        if self.filename != '':
            self.datei_gewaehlt['text']=self.filename
        
    def dateiname_vorschau(self):
        self.newName = self.var_abschluss.get()+"_"+self.var_studiengang.get()+"_"+self.var_modul.get()+"_"+self.var_semester.get()+"_"+self.var_dozent.get()+"_"+self.var_przr.get()+"_"+self.var_version.get()+"_"+self.var_note.get()+".pdf"
        self.vorschau_label['text']=self.newName
        
    def target_directory(self):
        self.EndPath = self.var_abschluss.get()+"/"+self.var_studiengang.get()+"/"+self.var_modul.get()+"/"+self.var_dozent.get()     
        
    def new_name(self):
        self.newName = self.var_abschluss.get()+"_"+self.var_studiengang.get()+"_"+self.var_modul.get()+"_"+self.var_semester.get()+"_"+self.var_dozent.get()+"_"+self.var_przr.get()+"_"+self.var_version.get()+"_"+self.var_note.get()+".pdf"
        
        
    def make_dir(self):
        if not os.path.exists(self.EndPath):
            os.makedirs(self.EndPath)
           
    def save_file(self):
        self.drop_refresh()
        self.target_directory()
        self.new_name()
        self.make_dir()
        os.rename(self.filepath,self.EndPath+"/"+self.newName)
        print(self.EndPath+"/"+self.newName)

    def about(self):
        t = Toplevel(root)
        t.wm_attributes('-topmost',-1)
        t.wm_title("Impressum, About" )
        t.wm_geometry('500x600+10+10')
        l = Label(t, text="Impressum, etc" )
        l.pack(side="top", fill="both", expand=True)

    def add_dozent(self):
        self.drop_refresh()
        popup_add_dozent = Toplevel(root)
        popup_add_dozent.wm_attributes('-topmost',-1)
        popup_add_dozent.wm_title("Dozent hinzufügen" )
        popup_add_dozent.wm_geometry('250x100+10+350')
        #popup_add_dozent = Label(self.popup_add_dozent, text="Hier könnte ein Fließtext stehen" )
        
        Label(popup_add_dozent, text="Dozentenname").grid(row=0)
        
        Dozentenname = Entry(popup_add_dozent)
        Dozentenname.grid(row=0, column=1)
        
        # Hier muss noch die übergabe an die CSV gemacht werden.     
        # GGF ein weiters Popup mit der frage ob es übernommen werden soll
        Eingabeende = Button(popup_add_dozent,text="übernehmen", command=self.donothing)
        Eingabeende.grid(row=4, column=1)

    def add_modul(self):
        self.drop_refresh()        
        popup_add_modul = Toplevel(root)
        popup_add_modul.wm_attributes('-topmost',-1)
        popup_add_modul.wm_title("Modul hinzufügen" )
        popup_add_modul.wm_geometry('300x100+10+500')
        #popup_add_dozent = Label(self.popup_add_dozent, text="Hier könnte ein Fließtext stehen" )
        
        Label(popup_add_modul, text="Abschluss  ").grid(row=0,column=0,sticky='w')
        Label(popup_add_modul, text="Studiengang  ").grid(row=1,column=0,sticky='w')
        Label(popup_add_modul, text="Modulname  ").grid(row=2,column=0,sticky='w')
        
        drop_abschluss = ttk.Combobox(popup_add_modul,textvariable=self.var_abschluss,values=self.lst_abschluss)
        drop_abschluss.grid(row=0,column=1)
        if drop_abschluss.get() == "Bachelor":
            drop_studiengang = ttk.Combobox(popup_add_modul,textvariable=self.var_studiengang_BA,values=self.lst_studiengang)
            drop_studiengang.grid(row=1,column=1) 
        elif drop_abschluss.get() == "Master":
            drop_studiengang = ttk.Combobox(popup_add_modul,textvariable=self.var_studiengang_MA,values=self.lst_studiengang)
            drop_studiengang.grid(row=1,column=1)        
        else: 
            print ('Bitte Abschluss angeben')  
        
        modulname = Entry(popup_add_modul)
        modulname.grid(row=2, column=1)
        
        # Hier muss noch die übergabe an die CSV gemacht werden.
        # GGF ein weiters Popup mit der frage ob es übernommen werden soll
        Eingabeende = Button(popup_add_modul,text="übernehmen", command=self.donothing)
        Eingabeende.grid(row=4, column=1)

    def del_dozent(self):
        popup_del_dozent = Toplevel(root)
        popup_del_dozent.wm_attributes('-topmost',-1)
        popup_del_dozent.wm_title("Dozent entfernen" )
        popup_del_dozent.wm_geometry('250x100+260+350')
        #popup_del_dozent = Label(self.popup_add_dozent, text="Hier könnte ein Fließtext stehen" )
        
        Label(popup_del_dozent, text="Dozentenname").grid(row=0)
        
        Dozentenname = Entry(popup_del_dozent)
        Dozentenname.grid(row=0, column=1)
        
        # Hier muss noch die übergabe an die CSV gemacht werden.     
        # GGF ein weiters Popup mit der frage ob es übernommen werden soll
        Eingabeende = Button(popup_del_dozent,text="übernehmen", command=self.donothing)
        Eingabeende.grid(row=4, column=1)

    def del_modul(self):
        self.popup_del_modul = Toplevel(root)
        self.popup_del_modul.wm_attributes('-topmost',-1)
        self.popup_del_modul.wm_title("Modul entfernen" )
        self.popup_del_modul.wm_geometry('250x100+260+500')
        #popup_del_dozent = Label(self.popup_add_dozent, text="Hier könnte ein Fließtext stehen" )
        
       
        # Hier muss noch die übergabe an die CSV gemacht werden.
        # GGF ein weiters Popup mit der frage ob es übernommen werden soll
        Eingabeende = Button(self.popup_del_modul,text="übernehmen", command=self.donothing)
        Eingabeende.grid(row=4, column=1)

    


root = Tk()
root.title("LUIS Beuth Renamer") 
menubar=Menu(root)
root.config(menu=menubar)
root.wm_attributes('-topmost',-1)
root.wm_geometry('500x280+10+10') 
app = Application(master=root)
app.mainloop()
BlackJack

@Apex: Das ist alles ein bisschen zu unübersichtlich. Das sieht sehr stark nach einer Gott-Klasse aus die alles kennt und alles macht. Das sind *viel* zu viele Attribute, die zudem auch noch in allen möglichen Methoden eingeführt werden und nicht nur in der `__init__()`.

Was soll bei ``import os as os`` und ``import csv as csv`` jeweil der ``as``-Teil? Das macht keinen Sinn.

Mehrzeilige Zeichenketten sind keine Kommentare.

Die ganzen `lst_*`-Präfixe sollten weg und die Namen in Mehrzahl benannt werdenen. Grunddatentypen haben in Namen nichts zu suchen.

`total_content` ist als Name ziemlich generisch und die ganzen magischen Indexwerte machen das Programm auch nicht leichter verständlich.

Es wird zu viel in die Fensterverwaltung eingegriffen. Fenstergrössen und dann auch noch Fensterpositionen sollten nicht fest vorgegeben werden, genau so wenig wie die ``topmost``-Option. Wenn die Fensterverwaltung nicht das macht was Du wünscht dann regel das auf Ebene der Fensterverwaltung. Umgekehrt kann man nämlich echt wahnsinnig werden wenn Anwendungen denken sie müssten das machen und es gehen dauernd Fenster auf falschen Bildschirmen auf oder drängeln sich in den Vordergrund oder ähnliches.
Apex
User
Beiträge: 8
Registriert: Montag 10. April 2017, 12:50

Hallo erstmal Danke für die schnelle antwort. Zu deinen Fragen/ Aussagen.
BlackJack hat geschrieben:Was soll bei ``import os as os`` und ``import csv as csv`` jeweil der ``as``-Teil? Das macht keinen Sinn.
Ich weiß leider auch nicht warum aber wenn ich es anders schreibe läuft es teilweise an verschiedenen Rechnern nicht. Ich finde es auch nicht schön aber erstmal läuft es und da ich noch nicht wirklich Fit mit Python bin blende ich solche unsinnigen Sachen aus bis es so läuft wie ich mir dass vorstelle :mrgreen:
BlackJack hat geschrieben:Die ganzen `lst_*`-Präfixe sollten weg und die Namen in Mehrzahl benannt werdenen. Grunddatentypen haben in Namen nichts zu suchen.
Ja ist auch nicht schön aber wie gesagt ich bin noch neu und habe dass als kleines Nebenprojekt. Daher habe ich es erstmal so geschrieben bis es sich bei mir gesetzt hat.
BlackJack hat geschrieben:`total_content` ist als Name ziemlich generisch und die ganzen magischen Indexwerte machen das Programm auch nicht leichter verständlich.
Ich lese an dieser Stelle eine CSV ein. Die Indexwerte beziehen sich auf die Zeilen in der CSV um die Daten einzuladen die ich brauche.

---------------
z.B.
(Zeile 0) Master,Bachelor
(Zeile 1) MA_BauIng, MA_UmweltIng, MA_GeoInfo
(Zeile 2) BA_BauIng, BA_UmweltIng, BA_GeoInfo
(Zeile 3) "Auflistung der Module MA_BauIng"
(Zeile 3) "Auflistung der Module MA_UmweltIng"
...
(Zeile 12) "Auflistung der Dozenten"

---------------

Ich möchte später Dozenten, Module etc noch löschen oder hinzufügen können, deswegen habe ich das in die CSV "ausgelagert"
BlackJack hat geschrieben:Es wird zu viel in die Fensterverwaltung eingegriffen.
Ist alles an sich unnötig, aber wie gesagt ich habe gerade erst angefangen und da sind noch "erste spielerein" drin. Das sollte aber auch kein problem beim eigentlichen Programm erzeugen.


Wie sieht es denn aus, kann man es sch schreiben dass wenn ich in einer Combobox z.B. Master "auswähle, die nächste Combobox mir nur die Masterstudiengänge anzeigt und wenn ich da einen ausgewählt habe mir in der dritten Box die Module des Studiengangs angezeigt werden.
BlackJack

@Apex: Programmieren ist kein Voodoo wo man irgendwelche Sachen macht die manchmal funktionieren und manchmal nicht. Wenn einem das so vorkommt, dann hat man etwas nicht richtig verstanden. Es kann nicht sein das auf einem Rechner ein ``import os`` funktioniert und auf einem anderen nicht und das man dort ``import os as os`` schreiben muss. Das macht überhaupt keinen Sinn das so zu schreiben!

Das mit den Grunddatentypen in Namen sollte sich gar nicht erst setzen. Besser jetzt nichts lernen was man sich hinterher wieder mühsam abgewöhnen muss. Und gute Namen sind *wichtig*, das ist keine Kosmetik die man später vielleicht mal nachreichen kann wenn es läuft, oder auch nicht, weil es läuft ja. Es geht nicht darum ob das Programm läuft sondern ob man es auch lesen und verstehen kann um auch tatsächlich Aussagen darüber treffen zu können ob es richtig läuft und was da überhaupt passiert.

`total_content` ist auch nach der Erklärung viel zu generisch und die Indexwerte viel zu magisch. Eine CSV-Datei ist ziemlich sicher nicht das geeignete Format für diese Daten, weil es sich nicht wirklich um 2D-Daten handelt bei denen mindestens die Spaltenwerte jeweils das gleiche bedeuten. Dafür sind CSV-Dateien geeignet. Entweder 2D-Daten oder ein Datensatz pro Zeile, aber nicht pro Zeile eine andere Liste von Daten.

Welche Probleme der Eingriff in die Fensterverwaltung haben kann, habe ich bereits angedeutet.
Apex
User
Beiträge: 8
Registriert: Montag 10. April 2017, 12:50

Soo, nach dem dieses Thema von BlackJack genutzt wurde um die Anzahl seiner getätigten Posts zu erhöhen, habe ich mir jetzt selber eine Lösung mit vielen IF- Schleifen geschaffen.

Ich würde ja sagen dass ich mich für die Hilfe bedanke aber dazu habe ich keinen Grund.

EDIT:
für die Admins: ich habe dass Thema eröffnet und sehe keinen Grund mehr es offen zu halten. Da hier eh nichts rum kam, könnt ihr das Thema gerne schließen bzw am besten gleich löschen
Antworten