Seite 1 von 1
Auf "namenlose" widgets zugreifen
Verfasst: Donnerstag 1. April 2010, 15:13
von asdman3000
Hi,
bin noch recht neu bei Tkinter und hab ein Problem bei einem Programm. Das Programm sollte über einen Button "Add" neue Text-Widgets einfügen, was auch gut klappt. Allerdings weiß ich nicht, wie ich auf die erstellten Text-Widgets zugreifen kann, weil sie keiner Variable zugeordnet sind. Wie kann ich auf "namenlose" widgets zugreifen?
Oder sollte ich das Ganze komplett anders aufbauen?
Hier das Script:
Code: Alles auswählen
from Tkinter import *
root = Tk()
x = 1
def addText():
global x
x = x + 1
Text(root, height = 12, width = 40).grid(row = x, column = 0, sticky = N, pady = 12, padx = 10)
addB.grid(row = x+1, column = 0)
addB = Button(root, text = "Add", command = addText, width = 15, bg = "#dddddd")
addB.grid(row = x+1, column = 0)
Text(root, height = 12, width = 40).grid(row = 1, column = 0, sticky = N, pady = 12, padx = 10)
root.mainloop()
Hoffe jemand kann mir helfen, vielen Dank im Voraus,
asdman3000
Verfasst: Donnerstag 1. April 2010, 15:35
von BlackJack
@asdman3000: Du könntest die Widgets in eine Liste stecken.
Das "globale" `x` ist nicht schön. Vergiss, dass es ``global`` überhaupt gibt. Spätestens bei GUIs sollte man objektorientierte Programmierung anwenden.
Verfasst: Freitag 2. April 2010, 11:51
von asdman3000
Danke für die Antwort,
Ich hab's so versucht:
Code: Alles auswählen
def addText():
global x
x = x + 1
liste[x-2] = Text(root, height = 12, width = 40)
liste[x-2].grid(row = x, column = 0, sticky = N, pady = 12, padx = 10)
addB.grid(row = x+1, column = 0)
funktioniert auch, aber wenn ich z.B. "print liste[1]" ausführe, wird ".60807248" oder eine andere Zahlenfolge ausgegeben. Jetzt frag ich mich, was das ".60807248" soll? ( "print liste[1].get("1.0", END)" funktioniert und gibt den Text aus dem zugehörigen Textfeld aus)
Das "globale" `x` ist nicht schön. Vergiss, dass es ``global`` überhaupt gibt. Spätestens bei GUIs sollte man objektorientierte Programmierung anwenden.
Wie funktioniert das ohne "global"? Welchem Objekt soll die Variable zugewiesen werden?
Danke im Voraus,
asdman3000
Verfasst: Freitag 2. April 2010, 12:59
von BlackJack
@asdman3000: Was mich an dem Quelltextschnippsel ein wenig wundert ist dass Du da einfach so an die Indexe in der Liste etwas zuweisen kannst. Was enthält die Liste denn da vorher? Ich hätte da eher erwartet, dass Du an die Liste einfach hinten Objekte anhängst. Dann brauchst Du das `x` auch nicht.
'.60807248' ist halt eine Zeichenkettendarstellung eines Tkinter-Widgets die eindeutig ist. Das ist irgendwas Tk-internes. Macht ja auch nicht viel Sinn ein GUI-Widget zu ``print``\en.
Ohne ``global`` arbeitet man indem man entweder Werte nur über die Argumente und die Rückgabewerte durch Funktionen schleust, oder eben OOP verwendet. Das Objekt muss da schon von Dir kommen. Zum Beispiel ein eigenes Widget das diese Textwidget-Liste kapselt.
Verfasst: Freitag 2. April 2010, 13:00
von EyDu
Hallo.
Du willst Parameter und Rückgabewerte statt global.
Deine Liste "liste" sieht auch nicht sehr gelungen aus. Hast du die irgendwo vorbefüllt? "append" sollte vollkommen ausreichen. Auch ist der Name natürlich sehr schlecht gewählt.
Sebastian
Verfasst: Samstag 3. April 2010, 00:02
von Pascal
root.winfo_children() liefert dir eine Liste mit allen Widgets.
Verfasst: Samstag 3. April 2010, 19:01
von asdman3000
Danke nochmal,
durch die Antworten ist mir einiges klarer geworden.
root.winfo_children() liefert dir eine Liste mit allen Widgets.
Wunderbar! Das erleichtert einiges und ich brauch meine Liste gar nicht mehr, vielen Dank!
asdman3000
Verfasst: Samstag 3. April 2010, 20:33
von BlackJack
@asdman3000: So wunderbar ist das IMHO nicht. Man sollte dafür eine eigene Datenstruktur mit einem passenden Namen verwenden.
Verfasst: Mittwoch 7. April 2010, 14:22
von yipyip
Nimm eine Liste. Und mit ein wenig OOP loest sich auch das Problem der "namenlosen Widgets" in Wohlgefallen auf.
Code: Alles auswählen
import Tkinter as tk
class Gui(object):
def __init__(self):
self.root = tk.Tk()
self.texts = []
self.button = tk.Button(self.root, text="Add", command=self.add_text, width=15)
self.act_row = 0
self.add_text()
def add_text(self):
text = tk.Text(self.root, height=2, width=40)
text.grid(row=self.act_row, column=0, sticky=tk.N)
self.texts.append(text)
self.act_row += 1
self.button.grid_forget()
self.button.grid(row=self.act_row, column=0)
self.test()
def test(self):
for i, text in enumerate(self.texts):
text.insert(tk.END, '%d ' % i)
def run(self):
self.root.mainloop()
if __name__ == '__main__':
Gui().run()
yipyip