GUI funktioniert nur in PyCharm

Fragen zu Tkinter.
Antworten
Jan197
User
Beiträge: 3
Registriert: Dienstag 4. Juni 2019, 09:22

Servus Leute,

Ich muss gerade mit einem Kommilitonen zusammen mit dem Raspberry Pi und Python eine Oberfläche machen, die zum Lesen und Beschreiben von RFID-Karten verwendet werden soll.
Hierfür hatte ich für den Anfang Zuhause schon mal den Code geschrieben, welcher unten zu finden ist, verwendet habe ich PyCharm und hatte beim ausführen auf dem Rechner keinerlei Probleme,
wenn wir aber nun versuchen ihn über den Raspberry Pi laufen zu lassen funktioniert es nicht, bzw. öffnet sich ein Fenster, mit dem allerdings nichts gemacht werden kann.
Eine Fehlermeldung wird nicht ausgegeben :/


Hoffe jemand hat eine Idee woran es liegen kann


Gruß



Code: Alles auswählen

from tkinter import *



Start = Tk()                  #Fenster erzeugen
Start.configure(background="white", borderwidth=15, relief=RAISED)
Start.overrideredirect(True)
Start.title("RFID Bezahl-System")    #Fenster Titel
Start.geometry("900x800+500+150")     #Fenster Größe

Bild1 = PhotoImage(file="c:\\HS2.gif")
canvas = Canvas(Start, width=350, height=100, highlightthickness=0)
canvas.place(x=500, y= 660)
canvas.create_image(0, 0, anchor=NW, image=Bild1)


Text1= Text(Start, height=1, width=20)
Text1.place(x=300, y=100)
Text1.insert(END, "Was möchten Sie tun?")
Text1.configure(border=0, font=("Arial", 20))



def StartAufrufen():
    Start.focus_force()

def KarteAnlegenAufrufen():
    KarteAnlegen.focus_force()

def DatenAbfragenAufrufen():
    DatenAbfragen.focus_force()

def GeldAufladenAufrufen():
    GeldAufladen.focus_force()

def BezahlenAufrufen():
    Bezahlen.focus_force()

def Beenden():
    KarteAnlegen.quit()





button1 = Button(Start, text="Neue Karte anlegen", command=KarteAnlegenAufrufen)   #Button1 erzeugen
button1.place(x=300, y=200)                                                       #Button1 Position
button1.config( font=("Arial", 20))


KarteAnlegen = Tk()  # Fenster erzeugen
KarteAnlegen.configure(background="white",borderwidth=15, relief=RAISED)
KarteAnlegen.overrideredirect(True)
KarteAnlegen.title("Neue Karte anlegen")  # Fenster Titel
KarteAnlegen.geometry("900x800+500+150")  # Fenster Größe


Text2= Text(KarteAnlegen, height=1, width=20)
Text2.place(x=250, y=250)
Text2.insert(END, "Matrikelnummer:")
Text2.configure(border=0, font=("Arial", 20))


NeueMatrikelnummer = Entry(KarteAnlegen) # Feld für neue Matrikelnummer
NeueMatrikelnummer.place(x=500, y=250)


button11 = Button(KarteAnlegen, text="Zurück", command=StartAufrufen)
button11.place(x=5, y=5)
button11.config( font=("Arial", 20))

button12 = Button(KarteAnlegen, text="Beenden", command=Beenden)
button12.place(x=710, y=5)
button12.config(font=("Arial", 20))

button13 = Button(KarteAnlegen, text="Karte beschreiben")
button13.place(x=300, y=400)
button13.config(font=("Arial", 20))




button2 = Button(Start, text="Daten abfragen",command=DatenAbfragenAufrufen)
button2.place(x=325, y=300)
button2.config( font=("Arial", 20))

DatenAbfragen= Tk()
DatenAbfragen.configure(background="white",borderwidth=15, relief=RAISED)
DatenAbfragen.overrideredirect(True)
DatenAbfragen.title("Daten abfragen")
DatenAbfragen.geometry("900x800+500+150")





button21 = Button(DatenAbfragen, text="Zurück", command=StartAufrufen)
button21.place(x=5, y=5)
button21.config( font=("Arial", 20))
button22 = Button(DatenAbfragen, text="Beenden", command=Beenden)
button22.place(x=710, y=5)
button22.config(font=("Arial", 20))

button23 = Button(DatenAbfragen, text="Abfragen")
button23.place(x=250, y=250)
button23.config(font=("Arial", 20))



button3 = Button(Start, text="Geld aufladen",command=GeldAufladenAufrufen)
button3.place(x=332, y=400)
button3.config( font=("Arial", 20))

GeldAufladen=Tk()
GeldAufladen.configure(background="white",borderwidth=15, relief=RAISED)
GeldAufladen.overrideredirect(True)
GeldAufladen.title("Geld aufladen")
GeldAufladen.geometry("900x800+500+150")




button31 = Button(GeldAufladen,text="Zurück",command=StartAufrufen)
button31.place(x=5, y=5)
button31.config(font=("Arial", 20))
button32 = Button(GeldAufladen, text="Beenden", command=Beenden)
button32.place(x=710, y=5)
button32.config(font=("Arial", 20))




button4 = Button(Start, text="Bezahlen",command=BezahlenAufrufen)
button4.place(x=356, y=500)
button4.config(font=("Arial", 20))

Bezahlen=Tk()
Bezahlen.configure(background="white",borderwidth=15, relief=RAISED)
Bezahlen.overrideredirect(True)
Bezahlen.title("Bezahlen")
Bezahlen.geometry("900x800+500+150")



button41 = Button(Bezahlen,text="Zurück",command=StartAufrufen)
button41.place(x=5, y=5)
button41.config(font=("Arial", 20))
button42 = Button(Bezahlen, text="Beenden", command=Beenden)
button42.place(x=710, y=5)
button42.config(font=("Arial", 20))



button5 = Button(Start,text="Beenden",command=Beenden)
button5.place(x=710, y=5)
button5.config( font=("Arial", 20))




mainloop()
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Keine *-Importe verwenden. Tkinter wird üblicherweise per `import tkinter as tk` imporiert und alle tk-Objekte per tk.xyz angesprochen.
Es darf nur eine Tk-Instanz im gesamten Programm geben. Wenn man mehrere Fenster möchte werden weitere Fenster per TopLevel erzeugt.

place ist eine schlechte Idee, vor allem, wenn man für verschiedene Systeme gleichzeitig entwickelt. Was unter Windows vielleicht ordentlich aussieht, wird beim Raspi unlesbar sein. Benutze grid oder pack.
Namenskonvention für Varialben ist klein_mit_unterstrich. Alles was auf oberster Ebene steht und keine Definition ist, sollte in Funktionen verschoben werden, üblicherweise gibt es eine Funktion main, die am Ende des Programms per `if __name__ == '__main__': main()` aufgerufen wird.
Das verhindert auch, dass aus Versehen globale Variablen in anderen Funktionen verwendet werden, denn alles was eine Funktion braucht, sollte sie über ihre Argumente bekommen. Die ganzen Funktionen, die Ihr definiert habt, sind aber überflüssig, weil man bei command= auch direkt so etwas wie Bezahlen.focus_force angeben könnte.

Warum werden text oder width beim Erzeugen der Tk-Widgets angegeben, font aber nachträglich per configure gesetzt?
Jan197
User
Beiträge: 3
Registriert: Dienstag 4. Juni 2019, 09:22

Vielen Dank für deine Hilfe
Wir haben beide keine Ahnung davon und den Code einfach mal irgendwie zusammen geschustert deswegen sieht er für erfahrene wohl ziemlich kacke aus haha
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt 5 Fenster gleichzeitig geöffnet zu haben, und sie gegenseitig zu überdecken, indem Ihr sie alle an die gleiche Position setzt, sollte man immer nur eine Fenster, bzw. ein Modalfenster geöffnet haben. Alternativ könnt Ihr hier mit einem Fenster arbeiten, das 5 Frames enthält, wobei die Unterframes erst dann erzeugt werden sollten, wenn sie gebraucht werden.

Das ganze könnte so aussehen:

Code: Alles auswählen

from functools import partial
import tkinter as tk

class KarteAnlegen(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        tk.Label(self, text="Neue Karte anlegen").place(x=300, y=100)
        tk.Label(self, text="Matrikelnummer:").place(x=250, y=250)
        self.neue_matrikelnummer = tk.Entry(self)
        self.neue_matrikelnummer.place(x=500, y=250)
        tk.Button(self, text="Zurück", command=self.destroy).place(x=5, y=5)
        tk.Button(self, text="Karte beschreiben", command=self.write).place(x=300, y=400)

    def write(self):
        # TODO: write card
        pass

class DatenAbfragen(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        tk.Label(self, text="Daten abfragen").place(x=300, y=100)
        tk.Button(self, text="Zurück", command=self.destroy).place(x=5, y=5)
        tk.Button(self, text="Abfragen").place(x=250, y=250)

class GeldAufladen(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        tk.Label(self, text="Geld aufladen").place(x=300, y=100)
        tk.Button(self, text="Zurück", command=self.destroy).place(x=5, y=5)
        tk.Button(self, text="Aufladen").place(x=250, y=250)

class Bezahlen(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        tk.Label(self, text="Bezahlen").place(x=300, y=100)
        tk.Button(self, text="Zurück", command=self.destroy).place(x=5, y=5)
        tk.Button(self, text="Bezahlen").place(x=250, y=250)


class Menu(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.root = root
        self.bild = tk.PhotoImage(file="c:\\HS2.gif")
        canvas = tk.Canvas(self, width=350, height=100, highlightthickness=0)
        canvas.place(x=500, y= 660)
        canvas.create_image(0, 0, anchor=NW, image=self.bild)

        tk.Label(self, text="Was möchten Sie tun?", height=1, width=20).place(x=300, y=100)
        tk.Button(self, text="Neue Karte anlegen", command=partial(self.switch,KarteAnlegen)).place(x=300, y=200)
        tk.Button(self, text="Daten abfragen",command=partial(self.switch,DatenAbfragen)).place(x=325, y=300)
        tk.Button(self, text="Geld aufladen",command=partial(self.switch,GeldAufladen)).place(x=332, y=400)
        tk.Button(self, text="Bezahlen",command=partial(self.switch,Bezahlen)).place(x=356, y=500)
        tk.Button(self, text="Beenden",command=root.quit).place(x=710, y=5)

    def switch(self, cls):
        cls(self.root).grid(row=0,column=0, sticky=tk.N+tk.S+tk.E+tk.W)

def main():
    root = tk.Tk()
    root.configure(background="white", borderwidth=15, relief=tk.RAISED)
    tk.Grid.rowconfigure(root, 0, weight=1)
    tk.Grid.columnconfigure(root, 0, weight=1)
    #root.overrideredirect(True)
    root.title("RFID Bezahl-System")    #Fenster Titel
    root.geometry("900x800+500+150")     #Fenster Größe
    Menu(root).grid(row=0,column=0, sticky=tk.N+tk.S+tk.E+tk.W)
    root.mainloop()

if __name__ == '__main__':
    main()
Jan197
User
Beiträge: 3
Registriert: Dienstag 4. Juni 2019, 09:22

Nochmals vielen Dank für deine klasse Hilfe, die Lösung mit den Frames funktioniert nun optimal, hast uns damit sehr weitergeholfen
Antworten