Anwendung von __dict__[]
Dictionaries sehen bereits nach dem richtigen Weg aus. Aber um meine Frage von oben noch einmal auf Dictionaries anzuwenden: was genau meinst du mit "Namensraum"? Gibt es zu jedem Schlüssel eine vorher bekannte Anzahl an Variablen und ist die Anzahl der Variablen bei allen Schlüsseln gleich? Handelt es sich nur um Daten oder sind es eher Objekte?
Das Leben ist wie ein Tennisball.
-
- User
- Beiträge: 132
- Registriert: Dienstag 15. März 2011, 15:43
Ich kriegs nicht hin. Die Checkboxen werden einfach nicht gestzt, obwohl die Werte im "TestDict"-Dictionary stehen. Hier mal nur für einen Namen:
(Korrektur: Es funktioniert doch, aber seltsamerweise nur in diesem Minimalbeispiel. Ich werde mal sehen, wo der Fehler ist ...)
(Korrektur: Es funktioniert doch, aber seltsamerweise nur in diesem Minimalbeispiel. Ich werde mal sehen, wo der Fehler ist ...)
Code: Alles auswählen
import Tkinter
TestDict = {'eins': '1', 'zwei': '0'}
class TestClass(object): pass
MasterName = Tkinter.Tk()
i = 0
TestInstance = TestClass()
for Test in TestDict:
setattr(TestInstance, Test, Tkinter.IntVar())
TestInstance.__dict__[Test].set(int(TestDict[Test]))
Tkinter.Checkbutton(MasterName, text = Test, variable = TestInstance.__dict__[Test]).grid(sticky = Tkinter.W, row = i, column = 0, columnspan = 1)
i = i + 1
MasterName.mainloop()
Ich habe dein vorheriges Script auch noch gesehen... Was zur Hölle tust du da? Nochmal und das gilt für beide Scripte - Finger weg von .__dict__
Vieleicht wäre es besser mal den Sinn dahinter zu erklären warum du solch eine Strucktur brauchst, dann könnte man vieleicht eine adäquat Lösung finden.
Vieleicht wäre es besser mal den Sinn dahinter zu erklären warum du solch eine Strucktur brauchst, dann könnte man vieleicht eine adäquat Lösung finden.
@hypnoticum: Ich würde mich dem anschliessen: Finger weg von `__dict__` und versuch doch mal "pythonischer" zu schreiben. Das mit der Gross-/Kleinschreibung führt zum Beispiel IMHO immer wieder zu Verständnisproblemen -- wenn etwas mit einem Grossbuchstaben beginnt, dann ist das in den Köpfen von Pythonprogrammierern der Name einer Klasse und man muss immer umdenken wenn dem dann nicht so ist. Dann kann man sich auch Zusätze wie `Class` oder `Instance` sparen, denn dann ist klar das `Test` eine Klasse und `test` ein Exemplar ist.
`MasterName` ist irreführend, weil es kein Name ist.
Das manuelle hochzählen von `i` würde man eher durch `enumerate()` ersetzen und wenn Du in der Schleife immer auch den Wert zu einem Schlüssel benötigst, kannst Du auch gleich über die Schlüssel/Wert-Paare iterieren. So sieht das IMHO auch deutlich "aufgeräumter" aus:
`MasterName` ist irreführend, weil es kein Name ist.
Das manuelle hochzählen von `i` würde man eher durch `enumerate()` ersetzen und wenn Du in der Schleife immer auch den Wert zu einem Schlüssel benötigst, kannst Du auch gleich über die Schlüssel/Wert-Paare iterieren. So sieht das IMHO auch deutlich "aufgeräumter" aus:
Code: Alles auswählen
import Tkinter as tk
name2value = {'eins': '1', 'zwei': '0'}
class Test(object):
pass
master = tk.Tk()
test = Test()
for i, (name, value) in enumerate(name2value.iteritems()):
int_var = tk.IntVar()
int_var.set(int(value))
setattr(test, name, int_var)
checkbutton = tk.Checkbutton(master, text=name, variable=int_var)
checkbutton.grid(sticky=tk.W, row=i, column=0)
master.mainloop()
-
- User
- Beiträge: 132
- Registriert: Dienstag 15. März 2011, 15:43
OK, vielen Dank für die Hilfe.
Ich werde versuchen mich hinsichtlich meiner Schreibweise zu bessern.
Eine weitere Frage habe ich aber noch. Die gehört dann eher in die Ecke Tkinter-Probleme:
Wenn ich die Variable vom Typ IntVar() in einem Toplevel-Fenster erzeuge, dann muss ich das komischerweise immer als Atttribut des Master-Fensters machen ("self.master.test"), damit die CheckButtons auch gesetzt werden. Eigentlich geht es doch das Master-fenster nichts an, oder?
Ich werde versuchen mich hinsichtlich meiner Schreibweise zu bessern.
Eine weitere Frage habe ich aber noch. Die gehört dann eher in die Ecke Tkinter-Probleme:
Wenn ich die Variable vom Typ IntVar() in einem Toplevel-Fenster erzeuge, dann muss ich das komischerweise immer als Atttribut des Master-Fensters machen ("self.master.test"), damit die CheckButtons auch gesetzt werden. Eigentlich geht es doch das Master-fenster nichts an, oder?
Code: Alles auswählen
from Tkinter import *
class TestGUI(object):
def __init__(self):
self.master = Tk()
self.init_widgets()
self.master.mainloop()
def init_widgets (self):
btn = Button(master = self.master,
text = 'Configure',
command = lambda: ConfigDia(self.master))
btn.pack()
class ConfigDia(object):
def __init__(self, Master):
self.master = Master
self.top = Toplevel()
self.init_widgets()
def init_widgets(self):
class Test(object):
pass
testDict = {'eins': '1', 'zwei': '0'}
self.master.test = Test()
for i, (name, value) in enumerate(testDict.iteritems()):
int_var = IntVar()
int_var.set(int(value))
setattr(self.master.test, name, int_var)
checkbutton = Checkbutton(self.top, text=name, variable=int_var)
checkbutton.grid(sticky=W, row=i, column=0)
newTestGUI = TestGUI()
Tut es auch nicht, aber dem Toplevel-Widget interessiert das sehr.
Und tut mir leid das so sagen zu müssen, aber dein Programm da oben entbehrt sich mir jeder Logik, du hast sowohl die OOP umgangen als auch die grundlegenden Struckturen von Tk. Du solltest dringend mal in das Tkinter-Unterforum oder auf effbot.org dir ansehen wie man mit Tkinter arbeitet. Ich wüsste jetzt gar nicht wo ich anfangen soll.
Und tut mir leid das so sagen zu müssen, aber dein Programm da oben entbehrt sich mir jeder Logik, du hast sowohl die OOP umgangen als auch die grundlegenden Struckturen von Tk. Du solltest dringend mal in das Tkinter-Unterforum oder auf effbot.org dir ansehen wie man mit Tkinter arbeitet. Ich wüsste jetzt gar nicht wo ich anfangen soll.
@hypnoticum: Es muss nicht das "Masterfenster" sein sondern halt irgend ein Objekt das auch bestehen bleibt. Dein `ConfigDia`-Objekt wird ja erstellt, aber da nirgends eine Referenz drauf gehalten wird, kann es auch sofort nachdem die `__init__()` fertig ist, wieder aus dem Speicher beseitigt werden. Und damit auch alle Attribute des Objekts.
Edit: Insofern ist es schon fast Zufall dass das `Toplevel` überhaupt dauerhaft angezeigt wird und nicht verschwindet. Selbst auf Tk-Seite ist es nicht explizit mit irgendeinem "Objekt" verbunden, weil Du beim erstellen vom `Toplevel` kein Eltern-Widget angibst. Das sollte man besser tun, sonst kann es dadurch auch zu komischen Effekten kommen.
Edit: Insofern ist es schon fast Zufall dass das `Toplevel` überhaupt dauerhaft angezeigt wird und nicht verschwindet. Selbst auf Tk-Seite ist es nicht explizit mit irgendeinem "Objekt" verbunden, weil Du beim erstellen vom `Toplevel` kein Eltern-Widget angibst. Das sollte man besser tun, sonst kann es dadurch auch zu komischen Effekten kommen.
-
- User
- Beiträge: 132
- Registriert: Dienstag 15. März 2011, 15:43
@Xynon1:
Tut mir leid, dass ich keine Zeit dafür habe mich da einzuarbeiten.
Ich muss es learning on the fly versuchen.
ICH BIN WEDER PROGRAMMIERER, NOCH INFORMATIKER.
Bisher konnte ich mir in MSVS meine GUI zusammenklicken.
Auch mit OOP hatte ich wenig Kontakt, hatte halt immer nur kleine Probleme ohne wirklich nötige Projektstruktur.
Ich kann nicht erst zu jedem Thema ein Buch was lesen bevor ich anfange. Ein Buch zu Python habe ich überflogen, aber bekanntlich steht in keinem Buch alles.
@BlackJack:
Also darum kann ich nun dem Toplevel-Widget zB. ein Attribut des master-Fensters bekannt machen, obwohl es in einem ganz anderen Dialog "hängt", das hilft mir weiter.
Tut mir leid, dass ich keine Zeit dafür habe mich da einzuarbeiten.
Ich muss es learning on the fly versuchen.
ICH BIN WEDER PROGRAMMIERER, NOCH INFORMATIKER.
Bisher konnte ich mir in MSVS meine GUI zusammenklicken.
Auch mit OOP hatte ich wenig Kontakt, hatte halt immer nur kleine Probleme ohne wirklich nötige Projektstruktur.
Ich kann nicht erst zu jedem Thema ein Buch was lesen bevor ich anfange. Ein Buch zu Python habe ich überflogen, aber bekanntlich steht in keinem Buch alles.
@BlackJack:
Also darum kann ich nun dem Toplevel-Widget zB. ein Attribut des master-Fensters bekannt machen, obwohl es in einem ganz anderen Dialog "hängt", das hilft mir weiter.
Diese Art von "learning on the fly" endet aber immer gleich man stürzt ab. Versuch es mal so:
Code: Alles auswählen
import Tkinter as tk
import tkSimpleDialog
class TestGUI(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, kwargs)
self.init_widgets()
def get_config(self):
config = ConfigDia(self)
print dir(config)
print config.eins
def init_widgets(self):
btn = tk.Button(self, text="Configure", command=self.get_config)
btn.pack()
class ConfigDia(tkSimpleDialog.Dialog):
def body(self, master):
test_dict = {'eins': '1', 'zwei': '0'}
for i, (name, value) in enumerate(test_dict.iteritems()):
int_var = tk.IntVar()
int_var.set(int(value))
setattr(self, name, int_var)
# Edit: self zu master gemacht
checkbutton = tk.Checkbutton(master, text=name, variable=int_var)
checkbutton.pack()
if __name__ == "__main__":
root = tk.Tk()
test = TestGUI(root)
test.pack()
root.mainloop()