Tkinter error

Fragen zu Tkinter.
Antworten
GuardDog

Hallo liebe Community,

ich bin gerade dabei in ein Menü ein "Listen-" und "Bildermodus" zu intergrieren. Der Code lautet wie folgt:

Code: Alles auswählen

from Tkinter import *
import os

def breakout():
	root.destroy()
	os.system("start "" breakout.bat")
def pong():
	root.destroy()
	os.system("start "" pong.bat")
def snake():
	root.destroy()
	os.system("start "" snake.bat")
def list():
    breakout_btn_img.destroy()
    pong_btn_img.destroy()
    snake_btn_img.destroy()
    list_btn.destroy()
    image_btn.grid(row=0, column=0)
    breakout_btn.grid(row=1, column=0)
    pong_btn.grid(row=2, column=0)
    snake_btn.grid(row=3, column=0)
def image():
    breakout_btn.destroy()
    pong_btn.destroy()
    snake_btn.destroy()
    image_btn.destroy()
    breakout_btn_img.grid(row=1, column=0)
    pong_btn_img.grid(row=2, column=0)
    snake_btn_img.grid(row=3, column=0)


root = Tk()
root.title("TheArcadeMachine")
root.resizable(False, False)

list_btn = Button(root, width=47, command=list, relief=SOLID, borderwidth=1, text="list mode")
breakout_img = PhotoImage(file="../img/breakout.gif")
breakout_btn_img = Button(root, width=333, height=127, image=breakout_img, command=breakout, relief=FLAT)
breakout.image = breakout_img
pong_img = PhotoImage(file="../img/pong.gif")
pong_btn_img = Button(root, width=333, height=127, image=pong_img, command=pong, relief=FLAT)
pong.image = pong_img
snake_img = PhotoImage(file="../img/snake.gif")
snake_btn_img = Button(root, width=333, height=127, image=snake_img, command=snake, relief=FLAT)
snake.image = snake_img
image_btn = Button(root, width=47, command=image, relief=SOLID, borderwidth=1, text="picture mode")
breakout_btn = Button(root, width=47, command=breakout, relief=FLAT, text="Breakout")
pong_btn = Button(root, width=47, command=pong, relief=FLAT, text="Pong")
snake_btn = Button(root, width=47, command=snake, relief=FLAT, text="Snake")



list_btn.grid(row=0, column=0)
breakout_btn_img.grid(row=1, column=0)
pong_btn_img.grid(row=2, column=0)
snake_btn_img.grid(row=3, column=0)
root.mainloop()
Leider bekomme ich diese mir unbekannte Fehlermeldung, die nur erscheint, wenn ich vom "Listenmodus" in den Bildmodus schalten möchte:

Code: Alles auswählen

"C:\Program Files (x86)\Python27\python.exe" D:/Tim/Dokumente/PythonProjects/TheArcadeMachine/data/src/main.py
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python27\lib\lib-tk\Tkinter.py", line 1542, in __call__
    return self.func(*args)
  File "D:/Tim/Dokumente/PythonProjects/TheArcadeMachine/data/src/main.py", line 27, in image
    breakout_btn_img.grid(row=1, column=0)
  File "C:\Program Files (x86)\Python27\lib\lib-tk\Tkinter.py", line 2029, in grid_configure
    + self._options(cnf, kw))
TclError: bad window path name ".56902040"

Desweiteren wäre ich über Kritik sehr erfreut


Grüße aus Hannover

GuardDog
Zuletzt geändert von GuardDog am Montag 10. April 2017, 11:58, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@GuardDog: Das ist alles ein bisschen zu unübersichtlich mit globalen Variablen statt Klassen, und zu vielen Codewiederholungen die man besser durch Schleifen, Funktionen, oder auch wieder Klassen strukturieren sollte. Es wird zu viel Gebrauch von `destroy()` gemacht. Danach ist das Widget ”kaputt” und kann nicht mehr verwendet werden. Ein sinnvolles vorgehen wäre die Anzeigeelemente nicht zu zerstören, sondern einfach wieder aus dem Layout zu nehmen. Und da es jeweils einen ganzen Satz von Anzeigeelementen gibt, die jeweils in einem `Frame` zusammen zu fassen und diese Frames anzuzeigen/aus der Anzeige zu nehmen, statt das mit den einzelnen Elementen zu tun.

Anstelle von `os.system()` sollte man das `subprocess`-Modul verwenden. Und zwar ohne ``shell=True`` als Argument!
GuardDog

Hi,

erstmal danke für deine Antwort. Wie nehme ich Widgets wieder aus dem Frame? (Habe nicht soviel mit Python am Hut, bin nen Anfänger :D )
BlackJack

@GuardDog: Mit der passenden `*_forget()`-Methode. Bei `grid()` also beispielsweise `grid_forget()`.
GuardDog

Danke es geht! Jetzt hätte ich noch zwei weitere Fragen: Wie macht man den Text in einem Button rechtsbündig? Und was hat es mit den Frames auf sich?

Der Code lautet nun wie folgt:
[codebox=python file=Unbenannt.txt]from Tkinter import *
import os

def breakout():
os.system("java -jar breakout.jar")
def pong():
os.system("java -jar pong.jar")
def snake():
os.system("java -jar snake.jar")
def list():
breakout_btn_img.grid_forget()
pong_btn_img.grid_forget()
snake_btn_img.grid_forget()
list_btn.grid_forget()
image_btn.grid(row=0, column=0)
breakout_btn.grid(row=1, column=0)
pong_btn.grid(row=2, column=0)
snake_btn.grid(row=3, column=0)
def image():
breakout_btn.grid_forget()
pong_btn.grid_forget()
snake_btn.grid_forget()
image_btn.grid_forget()
list_btn.grid(row=0, column=0)
breakout_btn_img.grid(row=1, column=0)
pong_btn_img.grid(row=2, column=0)
snake_btn_img.grid(row=3, column=0)


root = Tk()
root.title("TheArcadeMachine")
root.resizable(False, False)

list_btn = Button(root, width=47, command=list, relief=SOLID, borderwidth=1, text="list mode")
breakout_img = PhotoImage(file="../img/breakout.gif")
breakout_btn_img = Button(root, width=333, height=127, image=breakout_img, command=breakout, relief=FLAT)
breakout.image = breakout_img
pong_img = PhotoImage(file="../img/pong.gif")
pong_btn_img = Button(root, width=333, height=127, image=pong_img, command=pong, relief=FLAT)
pong.image = pong_img
snake_img = PhotoImage(file="../img/snake.gif")
snake_btn_img = Button(root, width=333, height=127, image=snake_img, command=snake, relief=FLAT)
snake.image = snake_img
image_btn = Button(root, width=47, command=image, relief=SOLID, borderwidth=1, text="picture mode")
breakout_btn = Button(root, width=47, command=breakout, relief=FLAT, text="Breakout")
pong_btn = Button(root, width=47, command=pong, relief=FLAT, text="Pong")
snake_btn = Button(root, width=47, command=snake, relief=FLAT, text="Snake")



list_btn.grid(row=0, column=0)
breakout_btn_img.grid(row=1, column=0)
pong_btn_img.grid(row=2, column=0)
snake_btn_img.grid(row=3, column=0)
root.mainloop()[/code]
BlackJack

@GuardDog: Schau Dir einfach mal die Optionen an die ein `Button` so kennt:
http://infohost.nmt.edu/tcc/help/pubs/t ... utton.html
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

[quote="GuardDog"]Danke es geht! Jetzt hätte ich noch zwei weitere Fragen: Wie macht man den Text in einem Button rechtsbündig? Und was hat es mit den Frames auf sich?

Defaultmäßig ist bei den Config Optionen gesetzt anchor="center". Stattdessen setzen: anchor="e"
Wenn der rechte Rand dann zu dick sein sollte, auch padx verringern. Standardmäßg gesetzt sind 3mm: padx="3m"
So etwa setzen "2m" oder "1m" oder auch in Pixel (ohne das "m").

Und Frames sind Container. Anstatt viele GUI Elemente in ein einziges Fenster zu knallen, kann man sie auf Frames legen und erhält so gut gegliederte Gruppierungen. Außerdem kann man dann auch leicht ganze GUI Teile sichtbar und wieder unsichtbar machen, etwa unsichtbar durch pack_forget() oder grid_remove() oder place_forget()
Antworten