StringVar in Liste definieren

Fragen zu Tkinter.
Antworten
AndiArbeit
User
Beiträge: 18
Registriert: Freitag 11. Juli 2014, 13:26

Montag 9. Mai 2016, 17:56

Guten Tag liebes Forum,

gleich zu meiner Frage...

ist es möglich ein StringVar in einer Liste zu deklarieren, damit ich mir den vorderen Teil sparen kann ?

Code: Alles auswählen

frameairbag = tk.StringVar()
ordner_airbag = tk.StringVar()

framecockpit = tk.StringVar()
ordner_cockpit = tk.StringVar()

all_includes = [
              [frameairbag,ordner_airbag],
              [framecockpit,ordner_cockpit]
              ]
also in etwa sowas. (oder eventuell das in Hübsch ;p)

Code: Alles auswählen


all_includes = [
              [frameairbag= tk.StringVar(),ordner_airbag= tk.StringVar()],
              [framecockpit= tk.StringVar(),ordner_cockpit= tk.StringVar()]
              ]
Gruß AndiArbeit
BlackJack

Montag 9. Mai 2016, 18:34

@AndiArbeit: Nein das ist so nicht möglich. Du kannst höchstens „tuple unpacking“ verwenden und so etwas schreiben:

Code: Alles auswählen

In [1]: a, b = xs = [42, 23]

In [2]: a
Out[2]: 42

In [3]: b
Out[3]: 23

In [4]: xs
Out[4]: [42, 23]
Edit: Das hat übrigens nichts mit den Typen von den Werten und damit auch nichts mit Tkinter zu tun.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 9. Mai 2016, 18:39

@BlackJack: Ich hatte den OP so verstanden, dass er lediglich die Objekte in eine Liste (genauer Liste von Listen) packen will - und das ist ja durchaus möglich. Wenn er tatsächlich denkt, dass er auf magische Art und Weise auch über die Namen ``frameairbag`` usw. auf die Listenelemente zugreifen will, geht das natürlich nicht.

Wenn man Werte derartig gruppieren und per lesbaren Namen auf die Elemente zugreifen will, böten sich ggf. namedtuples oder auch Dictionaries an (oder eben auch eine Klasse).
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3))
assert encoding_kapiert
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Dienstag 10. Mai 2016, 06:20

Code: Alles auswählen

all_includes = { 'frameairbag': tk.StringVar(), 'ordner_airbag': tk.StringVar(),
                 'framecockpit': tk.StringVar(), 'ordner_cockpit': tk.StringVar()}
                 
do_what_ever_u_want(all_includes['frameairbag'])
http://www.python-kurs.eu/dictionaries.php
AndiArbeit
User
Beiträge: 18
Registriert: Freitag 11. Juli 2014, 13:26

Dienstag 10. Mai 2016, 07:48

Danke für die Antworten.

Ich hätte vieleicht noch mehr von meinem Code posten sollen um mein Problem zu erläutern.

ich möchte eine Reihe von Frames erstellen die mit inhalt gefüllt werden. Das Problem ist das das "all_includes" etwa 20 Listeneinträge haben wird und der Inhalt muss im Nachhinein noch bearbeitet werden. Ich möchte also auf Grund der Übersichtlichkeit nicht 20 mal alle 6 variablen deklarieren und anschließend nochmal in die Liste schreiben.

Wahrscheinlich läuft das ganze auf Klassen hinaus womit ich aber keinerlei Erfahrung habe.

Code: Alles auswählen

frameairbag = tk.StringVar()
ordner_airbag = tk.StringVar()
datenairbag = tk.StringVar()
airbag_var = tk.StringVar()
airbag_var_basis = tk.StringVar()
airbag_dropdown = tk.StringVar()

framecockpit = tk.StringVar()
ordner_cockpit = tk.StringVar()
datencockpit = tk.StringVar()
cockpit_var = tk.StringVar()
cockpit_var_basis = tk.StringVar()
cockpit_dropdown = tk.StringVar()


all_includes = [
              [frameairbag, "Airbag","AIRBAG",ordner_airbag,datenairbag,airbag_var,airbag_var_basis,airbag_dropdown],
              [framecockpit, "Cockpit","COCKPIT",ordner_cockpit,datencockpit,cockpit_var,cockpit_var_basis,cockpit_dropdown],
              
              ]


for includes in all_includes :
  
  includes[0] = tk.Frame(framelinks , relief=tk.GROOVE)
  includes[0].pack(expand=1,fill=tk.BOTH)
  includes[0].config(bg = "white")

  schrifterstellen(includes[1],includes[0])

  includes[3].set(includes[2])
   
  includes[4] = os.listdir(link + "INCLUDES/" + includes[3].get())
  includes[4] = listeputzen(includes[4])
  includes[4].append("")

  includes[7] = tk.OptionMenu(includes[0], includes[5] , *includes[4] )
  includes[7].pack(expand=1 , fill=tk.BOTH , side=tk.LEFT )
  dropdownanpassen(includes[7])
  includes[5].trace("w",partial(trace_inc,[includes[5],includes[6],includes[7],includes[3]]))
Gruß AndiArbeit
Sirius3
User
Beiträge: 8805
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 10. Mai 2016, 08:02

@AndiArbeit: ja, Klassen wäre ein guter Ansatz. Bei GUI-Programmierung kommst Du da sowieso nicht dran vorbei. Du scheinst StringVar-Objekte als Platzhalter für Deine Listen zu benutzen. Dafür gibt es None:

Code: Alles auswählen

all_includes = [
    [None, "Airbag", "AIRBAG", ordner_airbag, None, airbag_var, airbag_var_basis, None],
    [None, "Cockpit", "COCKPIT", ordner_cockpit, None, cockpit_var, cockpit_var_basis, None],
]
Statt eine Liste zu erstellen und nachträglich die Einträge zu ändern, ist es in Python üblich, jeweils neue Listen zu erzeugen:


Obwohl eine Liste in Deinem Fall der falsche Datentyp ist. Wie Du bereits selbst erkannt hast, wäre eine Klasse besser geeignet. Das erkannst Du schon alleine daran, dass Du magische Indexwerte benutzt, die beim Lesen des Quelltextes nur Fragezeichen übrig lassen.

Code: Alles auswählen

all_folders = ["Airbag", "Cockpit"]
all_includes = []
for folder in all_folders:
    frame = tk.Frame(framelinks , relief=tk.GROOVE)
    frame.pack(expand=1,fill=tk.BOTH)
    frame.config(bg = "white")
    ordner = tk.StringVar()
    schrifterstellen(ordner, frame)
    ordner.set(folder.upper())
    files = os.listdir(os.path.join(link, "INCLUDES", ordner.get()))
    files = listeputzen(files)
    files.append("")
    var_needs_a_name = tk.StringVar()
    menu = tk.OptionMenu(frame, var_needs_a_name , *files )
    menu.pack(expand=1 , fill=tk.BOTH , side=tk.LEFT )
    dropdownanpassen(menu)
    var_needs_a_name.trace("w",partial(trace_inc, [var_needs_a_name, var_basis, menu, ordner]))
    all_includes.append([frame, folder, folder.upper(), ordner, files, var_needs_a_name, var_basis, menu])
Fang am besten gleich an, Klassen zu benutzen. Mit Deinem jetzigen Ansatz wirst Du nicht weiterkommen:

Code: Alles auswählen

class FileSelector(object):
    def __init__(self, framelinks, folder):
        self.folder = folder
        frame = tk.Frame(framelinks , relief=tk.GROOVE)
        frame.pack(expand=1,fill=tk.BOTH)
        frame.config(bg = "white")
        self.ordner = tk.StringVar()
        schrifterstellen(self.ordner, frame)
        self.ordner.set(folder.upper())
        files = os.listdir(os.path.join(link, "INCLUDES", self.ordner.get()))
        files = listeputzen(files)
        files.append("")
        self.var_needs_a_name = tk.StringVar()
        self.menu = tk.OptionMenu(frame, self.var_needs_a_name , *files)
        self.menu.pack(expand=1 , fill=tk.BOTH , side=tk.LEFT )
        dropdownanpassen(self.menu)
        self.var_needs_a_name.trace("w", self.trace_inc)
    
    def trace_inc(self, name, index, mode):
        #TODO: what ever

all_folders = ["Airbag", "Cockpit"]
all_includes = []
for folder in all_folders:
    all_includes.append(FileSelector(framelink, folder))
AndiArbeit
User
Beiträge: 18
Registriert: Freitag 11. Juli 2014, 13:26

Dienstag 10. Mai 2016, 08:43

Danke für die schnelle Hilfe.
Ich werde mich wohl mal in Klassen einarbeiten müssen :D
Antworten