Entry auslesen und in Textfenster ausgeben

Fragen zu Tkinter.
Antworten
Arachnid
User
Beiträge: 16
Registriert: Dienstag 27. Juli 2010, 18:32

Danke für die Hilfe schonmal. Ich galube mein Problem ist, dass ich keinen direkten Auslöser für den Befehl habe. BlackJack beispielsweise weist ja durch einen Button das Fenster an sich zu schließen. Bei mir steht der Befehl einfach in einer if-Funktion:

Code: Alles auswählen

def a1 (figa1):
	la1 = tk.Label(f, image=figa1, relief=tk.GROOVE)
	la1.pack()
	global bilda1
	bilda1 = figa1
	if c == 1:
		la1.forget()
Wobei der Block, der a1 aufruft auch c = 1 setzt. Es liegt definitiv nicht daran, dass er die if-Fuktion nicht aufruft, da ein print-Befehl,den ich zu Testzwecken dahinter geschrieben habe, ausgeführt wurde.
Glaubt ihr das könnte ein Problem sein? Oder habe ich mich doch in der Syntax vertan, denn momentan tut er nichts, wenn ich den Code da oben ausführe.
BlackJack

@Arachnid: Wo kommt `c` denn her? Und warum zeigst Du das Label im Falle von `c == 1` überhaupt an, wenn Du es dann sowieso gleich wieder entfernst!? Und was sind das für nichtssagende Namen? Warum steht da bei vielen `a1` als Postfix?

Zeig doch mal ein minimal lauffähiges Beispiel, dass das Verhalten zeigt, so dass man das auch nachvollziehen kann.

``if`` ist übrigens eine Anweisung und keine Funktion.
Arachnid
User
Beiträge: 16
Registriert: Dienstag 27. Juli 2010, 18:32

Das Problem ist, dass das Fenster grundsätzlich angezeigt werden soll und erst wenn c = 1 gesetzt wird, abgeschlatet werden soll. Und wenn ich es so einrichte, dass er das Fenster nur anzeigt solange c ungleich null ist, funktioniert es auch nicht. Er zeigt dann das Fenster immer noch an.
Dass da so oft a1 steht, liegt daran, dass das Fenster a1 heißt. Alle anderen entsprechenden Variablen beziehen sich also in irgendeinerweise auf das Fenster.
Ich hab bis jetzt immer nur Codeschnipsel gezeigt, weil das ganze Programm über 900 Zeilen lang ist und die entsprechenden Zeilen oft weit auseinander stehen, deswegen hab ich dir mal die entsprechenden Codezeilen zusammengebastelt:

Code: Alles auswählen

import Tkinter as tk
f = tk.Tk()
f.geometry('1000x700')
f.title('Schach')
f.iconbitmap('Schach_Icon.ico')
c = 0
a = 0
if a == 0:
	bilda1 = tk.PhotoImage(file='leer.gif')
	currentfigur = tk.PhotoImage(file='leer.gif')
leer = tk.PhotoImage(file='leer.gif')
bild = tk.PhotoImage(file='Schach700.gif')
TurmW = tk.PhotoImage(file='Turm.gif')
l = tk.Label(f, image=bild, relief=tk.GROOVE)
l.place(x=1, y=1)
def a1 (figa1):
	if c == 0:
		la1 = tk.Label(f, image=figa1, relief=tk.GROOVE)
		la1.place(x=18, y=631)
		global bilda1
		bilda1 = figa1
		# Hier soll jetzt la1 entfernt werden
def a2 (figa2):
	la1 = tk.Label(f, image=figa2, relief=tk.GROOVE)
	la1.place(x=18, y=544)
	global bilda2
	bilda2 = figa2
if a == 0:
	a1 (TurmW)
Zuganfang = tk.Text(f, height=39, width=15, relief=tk.GROOVE, background='black', foreground='white')
Zuganfang.place(x=720, y=60)
def show(self):
	Anfangskoordinate = ZuganfangEingabe.get()
	Zuganfang.insert(tk.END, Anfangskoordinate + "\n")
	ZuganfangEingabe.delete(0, tk.END)
	ZugendeEingabe.focus()
	a = 1
	if Anfangskoordinate == 'a1':
		global currentfigur
		currentfigur = bilda1
		global c
		c = 1
		a1 (leer)
def showend(self):
	Endkoordinate = ZugendeEingabe.get()
	Zugende.insert(tk.END, Endkoordinate + "\n")
	ZugendeEingabe.delete(0, tk.END)
	ZuganfangEingabe.focus()
	if Endkoordinate == 'a2':
		a2 (currentfigur)
ZuganfangEingabe = tk.Entry(f, width=10)
ZuganfangEingabe.place(x=720, y=1)
ZuganfangEingabe.focus()
ZuganfangEingabe.bind(sequence = '<Return>', func = show)
ZugendeEingabe = tk.Entry(f, width=10)
ZugendeEingabe.place(x=865, y=1)
ZugendeEingabe.bind(sequence = '<Return>', func = showend)
Zugende = tk.Text(f, height=39, width=15, relief=tk.GROOVE, background='black', foreground='white')
Zugende.place(x=865, y=60)
Zuganfang_Uberschrift = tk.Label(f, text='Zugstartfeld eingeben:  ', relief=tk.GROOVE, background='black', foreground='white')
Zuganfang_Uberschrift.place(x=720, y=41)
Zugende_Uberschrift = tk.Label(f, text='Zugendfeld eingeben:    ', relief=tk.GROOVE, background='black', foreground='white')
Zugende_Uberschrift.place(x=865, y=41)
f.mainloop()
Dieser Code ist ein Auszug, der das Programm im Miniformat darstellt. Leider kann ich hier nichts anhängen, sonst würde ich dir die Originalbilder mitliefern.
Und falls du befürchten solltest, dass ich ein richtiges Schachprogramm schreiben wollte, sei beruhigt, diese Programm soll nur Züge ausführen können, die ich eingebe. Ich werde ihm keine Schachregeln oder KI einprogrammieren. Nur, dass du nicht glaubst ich wäre jemand, der sich son Riesenprojekt vornimmt und dann irgendwann aufgibt, weil er sein Ziel nicht schnell genug erreicht.
Ich weiß auch, dass die place-Befehle nicht so schön sind, nur mit den Methoden, die ich zu erst ausprobiert habe und die zunächst auch funktioniert haben, brachten mich nicht weit, so dass ich erst mal wieder place-Befehle verwendet habe. Ich muss mich einfach nochmal intensiver mit dem Layoutmanager auseinandersetzen, das steht weit oben auf der Prioritätenliste.
Ich hoffe, dass das weiterhilft.
MfG
Arachnid
BlackJack

@Arachnid: Mit der entsprechenden `*_forget()`-Methode sollte das kein Problem sein, da steht ja aber nur ein Kommentar.

Aber grundsätzlich denke ich Du solltest das Vorhaben noch ein wenig verschieben und Grundlagen lernen. Funktionen und Datenstrukturen um da ein wenig Ordnung reinzubringen. Und ich denke OOP wäre ebenfalls eine sehr gute Idee.

So ein Schachfeld modelliert man nicht mit einzelnen Namen und Funktionen *pro* Feld. Das gehört in eine entsprechende Datenstruktur. Und da kann man sich auch ohne Grafik schon dransetzen.

Werte sollten Funktionen möglichst als Argumente betreten und als Rückgabewerte verlassen. Alles andere ist "magisch" und sehr unübersichtlich. Wenn sich mehrere Funktionen Werte "teilen" sollen, kann man sie mit einer Klasse zu Objekten zusammenfassen.

Auf Modulebene sollten möglichst nur Definitionen von Konstanten, Funktionen, und Klassen stehen und der Aufruf einer Hauptfunktion. Sonst kein ausführbarer Code.

Wenn Du das Schachfeld selber zeichnen möchtest, würde ich ein `Canvas` verwenden. Da kann man die Objekte auch nachträglich noch neu positionieren. Wenn der Hintergrund keine Grafik sein muss, bietet sich auch ein Frame mit einem 8x8 Grid darin an.
Arachnid
User
Beiträge: 16
Registriert: Dienstag 27. Juli 2010, 18:32

Das dieser Code im Endeffekt dämlich ist, war mir klar. Es war mehr oder weniger ein Notbehelf. Ich bin hier grade im Sommerlager und es gibt hier einfach nicht genug Platz, um gleichzeitig Schachfeld und Notebook aufzustellen und wir haben hier zwar Internet, das ist aber so langsam, dass es unmöglich ist ein Freeware-Programm runterzuladen. Da ich aber gerne auch hier noch ein bisschen Schach üben wollte, dachte ich mir, ich könnte mir so irgendwie aushelfen und es wär eine Superausgangsposition, um OOP und Ähnliches zu lernen.
Wie gesagt den forget-Befehl führt er einfach nicht aus. Na gut, geht auch so, lass ich eben leere Fenster stehen.
Vielen Dank euch nochmal.
Wenn ich in zwei Wochen zu Hause bin, werde ich mich dann dran setzen Python ordentlich zu lernen. Hier hab ich immer höchstens 2 Stunden am Stück Zeit, da ist es mir zu umständlich ständig wieder neu anzusetzen. Spiel ich eben Schach so gut es geht.
Vielen Dank nochmal.
MfG
Arachnid
Antworten