Auf "namenlose" widgets zugreifen

Fragen zu Tkinter.
Antworten
asdman3000
User
Beiträge: 17
Registriert: Donnerstag 1. April 2010, 15:05

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
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.
asdman3000
User
Beiträge: 17
Registriert: Donnerstag 1. April 2010, 15:05

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
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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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
Das Leben ist wie ein Tennisball.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

root.winfo_children() liefert dir eine Liste mit allen Widgets.
asdman3000
User
Beiträge: 17
Registriert: Donnerstag 1. April 2010, 15:05

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
BlackJack

@asdman3000: So wunderbar ist das IMHO nicht. Man sollte dafür eine eigene Datenstruktur mit einem passenden Namen verwenden.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

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()

:wink:
yipyip
Antworten