Seite 1 von 1

Was mach ich nur falsch???

Verfasst: Samstag 16. November 2002, 14:30
von Tux
Hi @ll!!!

import Tkinter
from Tkconstants import *

tk=Tkinter.Tk()
frame=Tkinter.Frame(tk)
frame.pack()

var=Tkinter.StringVar()
var2=Tkinter.StringVar()
var3=Tkinter.StringVar()
liste=[]
l1=Tkinter.Label(frame)
l1.grid(row=1,column=1)
l2=Tkinter.Label(frame)

def ok ():
a = var.get ()
b = var2.get()
c = var3.get()
d = [a, b, c]
f=open("C:/Python22/Schule/Projekt/liste.txt", "w")
liste.append(d)
l2['text']=liste
f.write (l2['text'])

def neu():
i=open("C:/Python22/Schule/Projekt/liste.txt", "w")
liste=[]
l2['text'] = liste
i.write(l2['text'])

e1=Tkinter.Entry(frame, relief=SUNKEN,borderwidth=3, textvariable=var)
e1.grid(row=2,column=1)
e2=Tkinter.Entry(frame, relief=SUNKEN,borderwidth=3, textvariable=var2)
e2.grid(row=2,column=2)
e3=Tkinter.Entry(frame, relief=SUNKEN,borderwidth=3, textvariable=var3)
e3.grid(row=2,column=3)

b1=Tkinter.Button(frame,text='Beenden',command=tk.destroy)
b1.grid(row=3,column=2)
b2=Tkinter.Button(frame,text='OK',command=ok)
b2.grid(row=3,column=1)
b3=Tkinter.Button(frame,text='Neu',command=neu)
b3.grid(row=3,column=3)

Tkinter.mainloop()

Das war erstma mein bisheriges Script!

Es funktioniert ganz gut! Doch wenn ich erst etwas ins Textdokument schreiben lasse, dann auf 'Neu' klicke und dann wieder was eingebe, ist es so, als hätte ich niemals auf 'Neu' geklickt! Wie kann ich das ändern???

Danke schon ma ICH

Verfasst: Samstag 16. November 2002, 16:30
von hans
wo ist dein f.close()? Wenn du die Datei nicht schließt, werden Änderungen unvollst#ändig / garnicht übernommen.

Hans

Funktioniert net!

Verfasst: Samstag 16. November 2002, 17:31
von Tux
Hi Hans!

Danke für den Tip, aber es funktioniert immer noch nicht!

ICH

Verfasst: Samstag 16. November 2002, 18:20
von hans

Code: Alles auswählen

def neu():
  i=open("C:/Python22/Schule/Projekt/liste.txt", "w")
  liste=[]
  l2['text'] = liste
  i.write(l2['text'])
  i.close()
Und das hat nicht geholfen? gibts da noch ne Methode flush()? Kann leider nicht direkt weiterhelfen, weil sich TKInter bei mir nicht installieren läßt (Konflikte!)

Hans

flush()???

Verfasst: Samstag 16. November 2002, 18:53
von Tux
i.close() hat nichts geholfen!

Was ist flush()???

Haste SuSE8.1 Hans???

ICH

Globale Variablen (war: Was mach ich nur falsch???)

Verfasst: Samstag 16. November 2002, 19:22
von Voges
Hallo Tux!

Sorry, ich muss mal ein wenig nörgeln:
- bitte GUI-lastige Beiträge auch im GUI-Forum veröffentlichen (gilt auch für Francescos Beitrag)
- vernünftiges Subject wählen
- Code bitte in [ CODE ]-Tags packen, damit die Einrückungen überleben.
- Genau schreiben, WAS nicht funktioniert bzw. welchen Zweck neu() denn erfüllen soll.
- Sich Tux zu nennen und dann Pfade mit "c:\" ... tststs ;-) ;-)

Also, neu() funktioniert einwandfrei, macht aber wohl nicht dass, was Du willst. Ich nehme an, sie soll die *globale* Liste leeren und dann diese in die Datei schreiben. Letzteres funktioniert einwandfrei (da hast Du Hans ganz schön zappeln lassen). Nur, Du löscht nicht die *globale* Liste sondern erzeugst eine neue und leere *lokale* Liste, denn wenn innerhalb einer Funktion einer Variablen ein Wert zugewiesen wird, ist sie automatisch *lokal*. Anders wäre es auch fatal, denn derjenige, der eine Funktion schreibt, kann ja nicht alle globalen Variablen kennen und würde so u.U. globale Variablen zerschießen.
Ok() funktioniert dagegen so, wie Du es Dir vorstellst, da dort keine Zuweisung erfolgt, sondern mit append() nur eine Manipulation der Liste, die es schon geben muss. Da Python im Namespace der Funktion kein liste findet, sucht der Interpreter im Namespace eine Ebene höher und wird fündig.
Lösung Deines konkreten Problems: Deklariere liste in der Funktion explizit als global:

Code: Alles auswählen

def neu():
  global liste
  liste=[]

hth
Jan

Verfasst: Samstag 16. November 2002, 19:43
von Milan
sorry voges, aber der Fehler ist ein anderer, oder besser zusätzlicher... :

Code: Alles auswählen

def neu(): 
    global liste
    i=open("C:/Python22/Schule/Projekt/liste.txt", "w") 
    liste=[] 
    l2['text'] = liste 
    i.write(l2['text']) 
    i.close() 
l2 ist doch nen Label und die akzeptieren nur Strings, das heißt du müsstest l2['text'] = str(liste) schreiben. Dasselbe in der Funktion ok(), da muss das gleiche gemacht werden und ein global muss ebenfalls gesetzt werden.

Verfasst: Samstag 16. November 2002, 20:25
von Voges
Hallo!
Milan hat geschrieben:l2 ist doch nen Label und die akzeptieren nur Strings, das heißt du müsstest l2['text'] = str(liste) schreiben. Dasselbe in der Funktion ok(), da muss das gleiche gemacht werden und ein global muss ebenfalls gesetzt werden.
Eben getestet. l2['text'] = liste klappt ausgezeichnet. Eine Umwandlung ist nicht nötig. Man sieht nur nichts, da das Label l2 nie in die Oberfläche eingefügt wurde (im Gegensatz zu l1). global ist übrigends auch nicht nötig, da bei l2['text'] = liste zwingend l2 vorhanden sein muss und so keine lokale Variable entstehen kann, sondern von einer globalen Variablen ausgegangen wird.

Jan

P

Verfasst: Samstag 16. November 2002, 23:39
von Tux
1. Voges: Dein nörgeln is ok - werd versuchen dran zu denken!
2. Voges: Auch wenn dort ein Pfad mit C: steht, heißt das noch lange nicht, dass ich im Windoofs arbeite (war nur gerade kurz dort, weil ich was gesucht hab - in einem Programm das wine nicht besonders mag) - Trotzdem tut es mir leid, dass ich nicht gleich wieder dort raus gegangen bin! :oops:

3. Voges und Milan: könnt ihr euch mal einigen???

4. Danke für die Lösungen! Irgendeine wird schon stimmen!


ICH

Lösungen!

Verfasst: Sonntag 17. November 2002, 00:02
von Tux
Hi Voges und Milan!

Ich hab eure beiden Lösungen mal getestet - resultat:
Es funktioniert immer noch nicht!!!

Hier mal die Textdatei (ich hab es umgeschrieben, sodass sich die Datei im Verzeichnis /home/ich/ befindet Voges) :

in den Entrys standen die Buchstaben 'd', 'a', 's':

Code: Alles auswählen

Beim klicken auf     Textdatei
=========================================================
       OK         [["d","a","s"]]
       OK         [["d","a","s"],["d","a","s"]]
       Neu        []
       OK         [["d","a","s"],["d","a","s"],["d","a","s"]] 
beim letzten OK sollte aber nur [["d","a","s"]] dastehen!!!

Habt ihr vielleicht noch ne gute Idee???

Danke schon mal ICH

Re: Lösungen!

Verfasst: Sonntag 17. November 2002, 00:35
von Voges
Hallo!
Tux hat geschrieben: beim letzten OK sollte aber nur [["d","a","s"]] dastehen!!!
Also, bei mir funktioniert es. Keine Typo, z.B. global Liste statt global liste oder sowas? Ansonsten poste nochmal die relevanten Teil.
Jan

Lösung

Verfasst: Sonntag 17. November 2002, 00:42
von Tux
Mir is noch ne Lösungsvariante eingefallen, wo ich aber die Umsetzung nicht genau kenne!

Theoretisch müsste es doch funktionieren, wenn ich bei der Definition ok erst alles aus der Textdatei auslese und dann an dieses Ausgelesene die neuen Werte anhänge und dann wieder in die Textdatei speichere!

Ich weiß aber nicht genau, wie das mit dem Auslesen geht (irgendwas mit f.read schätz ich mal - wie geht das aber genau???)

ICH

Re: Lösung

Verfasst: Sonntag 17. November 2002, 09:48
von Voges
Moin!

Ein Möglichkeit, wenn Du auf die umschließende Liste verzichten kannst:
Wenn Du die Datei mit "a" (append) statt mit "w" öffnest, bleibt der bisherige Inhalt erhalten und alles Neue wird hinten angefügt.

Code: Alles auswählen

def ok ():       # ungetestet!
	a = var.get (); b = var2.get(); c = var3.get()
	d = [a, b, c]
	f=open("C:/Python22/Schule/Projekt/liste.txt", "a")
	l2['text']=d
	f.write (l2['text'])
Für diesen Umweg über das unsichtbare Label wird Du Deine Gründe haben, nehme ich an.

Vorher einlesen geht natürlich auch. Wenn immer alles in einer Zeile ist, kannst Du diese eine Zeile einfach mit readline() einlesen, den neuen String ranhängen und das ganze wieder zurückschreiben.
Was für Dich die beste Lösung ist, hängt davon ab, was Du eigentlich mit dem Speichern bezweckst.

Jan

Verfasst: Sonntag 17. November 2002, 09:55
von Milan
hast du wirklich global liste am anfang hingeschrieben?, ich denke es könnte doch dran liegen, das er dann nur eine lokale liste leer macht, aber für das nicht lokale alles bleibt...

ansonsten geht das mit dem auslesen so:

Code: Alles auswählen

inhalt=open('dateiname','r').read() #erst mal alles als String in inhalt
inhalt=eval(inhalt) # inhalt wird zur Liste
inhalt.append(neuedaten) # neues wird angehangen
l2['text']=inhalt #der label wird neu beschriftet...
open('dateiname','w').write(l2['text']) # es werden die änderungen in die Datei geschrieben....
das geht aber nur, wenn du nur eine Liste in einer Zeile stehen hast, so wie in deinem Beispiel. ansonsten musst du den ausgelesenen String etwas bearbeiten, sodass du kleine bearbeitbare Teilstücke hast.

Verfasst: Sonntag 17. November 2002, 09:57
von Milan
ups, hab mir nen bissel viel zeit gelassen als ich geschreibselt hab... egal, jetzt hat Tux zwei Lösungen...

Danke

Verfasst: Sonntag 17. November 2002, 20:15
von Tux
Hi Voges und Max!

Es funktioniert! :D
Dank an euch!

ICH