Bereich neu zeichen

Fragen zu Tkinter.
Antworten
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Ich möchte ein Teilbereich einer Tkinteranwendung neu zeichen.
Auf Knopfdruck sollen neu eingelesene Daten angezeigt werden.
In meinem funktionierenden Beispiel wird ein grid aus Labels einfach (ich nenne es mal) überschrieben.

Ist das eine übliche Herangehensweise?
Was passiert mit den alten Labels? Verschwinden die einfach oder werden die nur eben nicht mehr angezeigt?

cu Sebastian


Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import Tix

liste = [ ["01.","Liste"],
    ["01.","Liste"],
    ["01.","Liste"],
    ["01.","Liste"],
    ["01.","Liste"],
    ["01.","Liste"] ]

liste2 = [ ["02","Liste"],
    ["02.","Liste"],
    ["02.","Liste"],
    ["02.","Liste"],
    ["02.","Liste"],
    ["02.","Liste"] ]

def draw_liste(liste_blub):
   for zeile, lst in enumerate(liste_blub):
      zeile2 = zeile +1

      for spalte, element in enumerate(lst):
         Tix.Label(win.window, text=element, bd=1, relief="ridge",
                  ).grid(row=zeile2, column=spalte)


root = Tix.Tk()
win = Tix.ScrolledWindow(root, scrollbar='auto',height=100)
win.pack()

draw_liste(liste)

box = Tix.ButtonBox(root)
box.add('import', text='lade Liste2', command=lambda root=root: draw_liste(liste2))
box.pack()

root.mainloop()
Benutzeravatar
Hannes-Spz
User
Beiträge: 123
Registriert: Sonntag 7. August 2005, 22:42

Tut mir leid, dass ich das ganze nicht auf Tix übertragen kann, aber bei Tk
ist es so, dass deine Labels jeweils eigenen Speicherplatz bekämen...

Code: Alles auswählen

from Tkinter import Tk, Label
r = Tk()
Label(r, text = "H" ).grid(row = 20, column = 20)
Label(r, text = "M" ).grid(row = 20, column = 20)
print r.winfo_children()
(mainloop braucht man ja in diesem beispiel nicht, da man ja nichts angezeigt
bekommen mag...)

du könntest, wenn es sowas in Tix gibt, mit der liste .winfo_children() alle
labels durchgehen und sie dann löschen...
(vorher würde ich sie aber auf einzelne frames legen damit du nur mittels
frame.winfo_children() die aus einem bestimmten bereich löscht und nicht
alle, die root aufweisen kann :wink: )
doch wie gesagt, ich weiß nicht, ob tix das hat..! :roll:

ansonsten
[size=85]"Unsere Situation ist immer die eines schwarzen Mannes der in einem schwarzen Keller einen schwarzen Hut sucht, den es vielleicht gar nicht gibt." Sir Karl R. Popper[/size]
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Danke für deine Antwort,
habe schon befürchtet mit Tix potentielle Antworter abgeschreckt zu haben ;-)

Aber wir können das gerne auch in pure Tkinter fortsetzen.
Dein Code bringt mir:

Code: Alles auswählen

<bound method Tk.winfo_children of <Tkinter.Tk instance at 0x4020a1ac>>
Nur was fange ich damit an?
Über winfo_children() bin ich schon auf Python.org gestolpert, nur konnte ich damit nix anfangen. Bin leider noch nicht so weit, dass ich ohne Anfängerbeispiele auskomme :-(



Edit:
Habe gerade gesehen, dass ich beim Kopieren die Klammern bei winfo_children() vergessen habe.
Jetzt sieht das Ergebnis so aus:

Code: Alles auswählen

[<Tkinter.Label instance at 0x4020a12c>, <Tkinter.Label instance at 0x4020d5cc>]
Und so gefällt es mir schon besser.
Werde jetzt erstmal ein wenig basteln und testen.

Danke für deine Hilfe
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Das habe ich mir zusamengebastelt:

Es werden ein paar Widgets (Label und Eingabefelder) erzeugt und auf Knopfdruck nacheinander entfernt.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from Tkinter import *
from time import sleep
import pprint
pp = pprint.PrettyPrinter(indent=2)


master = Tk()
frme = Frame(master, bg="red")
frme.grid(row=0, column=0)

Label(frme, text="First").grid(row=0)
Label(frme, text="Second").grid(row=1)
Entry(frme).grid(row=0, column=1)
Entry(frme).grid(row=1, column=1)

def loesche():
   for i in frme.winfo_children():
      print "loesche nun:\n  ", i,
      print " -> Widget Type:", i.winfo_class()

      # 2 Sekunden Verzoegerung, damit man den Loeschvorgang beobachten kann
      sleep(1)

      # hier wird das Widget geloescht
      i.destroy()

      # damit das Widget nicht mehr angezeigt wird aktualisieren wir dem Frame,
      # auf dem das Widget liegt.
      frme.update()
   print "loeschen beendet"


Button(master, text="loesche", command = loesche ).grid(row=1, column=0)

# zusaetzliche Infos, schick aufbereitet vom "pretty printer"
pp.pprint(frme.winfo_children())

master.mainloop()
Edit:

Code: Alles auswählen

i.winfo_class()
eingebaut
Zuletzt geändert von Mr_Snede am Mittwoch 22. März 2006, 11:19, insgesamt 2-mal geändert.
Benutzeravatar
Hannes-Spz
User
Beiträge: 123
Registriert: Sonntag 7. August 2005, 22:42

hab nochwas gefunden:

Code: Alles auswählen

li=root.winfo_children()
for i in li: print i.winfo_class()
das speichert erst, wie du weist, alle widgets(die adresse) in der liste,
die danach durchgegangen wird und ein wunderschönen string zurückgibt...

zb: [<__main__.Label instance at 0x00AF3F08>] wird zu "label"
(vl. auch groß geschrieben... :roll: )

:wink:
[size=85]"Unsere Situation ist immer die eines schwarzen Mannes der in einem schwarzen Keller einen schwarzen Hut sucht, den es vielleicht gar nicht gibt." Sir Karl R. Popper[/size]
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Habe direkt in den Code eingebaut und auch die Ausgabe etwas hübscher gestaltet:

Code: Alles auswählen

[ <Tkinter.Label instance at 0x4032fc2c>,
  <Tkinter.Label instance at 0x4032fc4c>,
  <Tkinter.Entry instance at 0x4032f66c>,
  <Tkinter.Entry instance at 0x4032f62c>]
loesche nun:
   .1077081740.1077083180  -> Widget Type: Label
loesche nun:
   .1077081740.1077083212  -> Widget Type: Label
loesche nun:
   .1077081740.1077081708  -> Widget Type: Entry
loesche nun:
   .1077081740.1077081644  -> Widget Type: Entry
loeschen beendet
Antworten