Was mach ich nur falsch???

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
hans
User
Beiträge: 728
Registriert: Sonntag 22. September 2002, 08:32
Wohnort: Sauerland
Kontaktdaten:

wo ist dein f.close()? Wenn du die Datei nicht schließt, werden Änderungen unvollst#ändig / garnicht übernommen.

Hans
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

Hi Hans!

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

ICH
hans
User
Beiträge: 728
Registriert: Sonntag 22. September 2002, 08:32
Wohnort: Sauerland
Kontaktdaten:

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
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

i.close() hat nichts geholfen!

Was ist flush()???

Haste SuSE8.1 Hans???

ICH
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

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
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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.
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

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
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

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
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

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
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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.
Zuletzt geändert von Milan am Sonntag 17. November 2002, 16:05, insgesamt 1-mal geändert.
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

ups, hab mir nen bissel viel zeit gelassen als ich geschreibselt hab... egal, jetzt hat Tux zwei Lösungen...
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

Hi Voges und Max!

Es funktioniert! :D
Dank an euch!

ICH
Antworten