Mehrere Fenster // Startseite -> Anmeldung -> Nächstes Fenster

Fragen zu Tkinter.
Antworten
l30n100
User
Beiträge: 19
Registriert: Sonntag 18. Februar 2018, 14:15

Sonntag 18. Februar 2018, 14:29

Schön guten Tag.
Ich bin neu in dem Forum und das hier ist mein erster Beitrag.

Ich bin noch recht neu im Bereich tkinter und wollte deswegen wissen, wie ich das machen kann.

Mein ziel ist es, dass wenn man die Anwendung startet man zur einer Startseite kommt, auf dem es zwei Buttons gibt, die
einem zu einem neuen Fenster bringen. Das eine Fenster ist ein Kopfrechentrainer und das andere sind Übungsblätter.

Nun ist mein Problem, dass mich die Lokalen Variablen total verwirren. Ich habe es schon bisschen versucht(siehe code),
aber nach der anmeldung weiß ich nicht wie man da nächste fenster öffnet, das alte schließt und auf dem neuen Fenster weiter macht.

import tkinter

#Login-Fenster Command
def login():
#Variable
#pwtest
def pwkopf():
eingabe = e2.get() #Passwort
eingabe1 = e1.get() #Nutzername
if eingabe == "123" and eingabe1 == "123":
login.destroy()
main.destroy()
#Kopfrechen
kmain = tkinter.Tk()
kmain.geometry("1000x580")
khead = tkinter.Label(kmain)
um = tkinter.PhotoImage(file="...")
khead["image"] = um
khead.pack()
kmain.iconbitmap("...")
kmain.title("Fiete Pauker - Kopfrechentrainer")
kmain.mainloop()
else:
ver["text"] = "Zugang verweigert!"
ver["font"] = "Arial 10"
ver["fg"] = "#FF0000"

login = tkinter.Tk()
login.title("Anmeldung")
login.geometry("261x130")
login.iconbitmap("...")
#Widgets
logintxt1 = tkinter.Label(login, text = "Bitte melden Sie sich an")
logintxt1["font"] = "Arial 10 bold"
logintxt1.place(relx = 0.5, y = 6, anchor = "n")

logintxt2 = tkinter.Label(login, text = "Benutzername:")
logintxt2["font"] = "Arial 10"
logintxt2.place(x = 10, y = 30, anchor = "nw")

e1 = tkinter.Entry(login)
e1.place(x = 120, y = 33, anchor = "nw")

logintxt3 = tkinter.Label(login, text = "Passwort:")
logintxt3["font"] = "Arial 10"
logintxt3.place(x = 10, y = 60, anchor = "nw")

e2 = tkinter.Entry(login, show = "*")
e2.place(x = 120, y = 60, anchor = "nw")

#Extras
def abb():
login.destroy()

abbruch = tkinter.Button(login, text = "Abbruch", command = abb)
abbruch.place(x = 188, y = 90, anchor = "nw")

los = tkinter.Button(login, text = "Login", command = pwkopf)
los.place(x = 135, y = 90, anchor = "nw")

ver = tkinter.Label(login)
ver.place(x = 14, y = 91)

login.mainloop()

#Command für Kopfrechen-Trainer
def demain():
head.destroy()
hallo.destroy()
meister.destroy()
kopf.destroy()
blatt.destroy()

#Haupseite
main = tkinter.Tk()
main.geometry("1000x580")
#Titelbild
head = tkinter.Label(main)
im = tkinter.PhotoImage(file="...")
head["image"] = im
head.pack()

#Begrüßungstext
hallo = tkinter.Label(main, text = """...""")
hallo.pack()
hallo["font"] = "Arial 20"

#Denn Übung macht den Meister!
meister = tkinter.Label(main, text = "Übung macht den Meister!")
meister.pack()
meister["font"] = "Arial 30"

#Button zum Kopfrechen-Trainer
kopf = tkinter.Button(main, text = "Zum Kopfrechentrainer", command = login)
kopf["bg"] = "#14ADA0"
kopf["fg"] = "#FFFFFF"
kopf["relief"] = "flat"
kopf["height"] = 3
kopf["width"] = 29
kopf["font"] = "Arial 15 bold"
kopf.pack(padx = 70, pady = 20, side = "left")

#Button zu den Übungsblättern
blatt = tkinter.Button(main, text = "Zu den Übungsblättern")
blatt["bg"] = "#1894CE"
blatt["fg"] = "#FFFFFF"
blatt["relief"] = "flat"
blatt["height"] = 3
blatt["width"] = 29
blatt["font"] = "Arial 15 bold"
blatt.pack(padx = 70, pady = 20, side = "right")


#Window Icon Set
main.iconbitmap("...")
main.title("Fiete Pauker")

main.mainloop()


Liebe Grüße.
Benutzeravatar
wuf
User
Beiträge: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Sonntag 18. Februar 2018, 20:41

Hi l30n100

Herzlich willkommen in unserem Forum. Probiere dein Skript nochmals in 'Code-Tags' zu präsentieren.

Gruss wuf :wink:
Take it easy Mates!
l30n100
User
Beiträge: 19
Registriert: Sonntag 18. Februar 2018, 14:15

Sonntag 18. Februar 2018, 22:30

l30n100 hat geschrieben:Schön guten Tag.
Ich bin neu in dem Forum und das hier ist mein erster Beitrag.

Ich bin noch recht neu im Bereich tkinter und wollte deswegen wissen, wie ich das machen kann.

Mein ziel ist es, dass wenn man die Anwendung startet man zur einer Startseite kommt, auf dem es zwei Buttons gibt, die
einem zu einem neuen Fenster bringen. Das eine Fenster ist ein Kopfrechentrainer und das andere sind Übungsblätter.

Nun ist mein Problem, dass mich die Lokalen Variablen total verwirren. Ich habe es schon bisschen versucht(siehe code),
aber nach der anmeldung weiß ich nicht wie man da nächste fenster öffnet, das alte schließt und auf dem neuen Fenster weiter macht.

Code: Alles auswählen

import tkinter

#Login-Fenster Command
def login():
    #Variable
        #pwtest
    def pwkopf():
        eingabe = e2.get() #Passwort
        eingabe1 = e1.get() #Nutzername
        if eingabe == "123" and eingabe1 == "123":
            login.destroy()
            main.destroy()
            #Kopfrechen
            kmain = tkinter.Tk()
            kmain.geometry("1000x580")
            khead = tkinter.Label(kmain)
            um = tkinter.PhotoImage(file="...")
            khead["image"] = um
            khead.pack()
            kmain.iconbitmap("...")
            kmain.title("Fiete Pauker - Kopfrechentrainer")
            kmain.mainloop()
        else:
            ver["text"] = "Zugang verweigert!"
            ver["font"] = "Arial 10"
            ver["fg"] = "#FF0000"
            
    login = tkinter.Tk()
    login.title("Anmeldung")
    login.geometry("261x130")
    login.iconbitmap("...")
    #Widgets
    logintxt1 = tkinter.Label(login, text = "Bitte melden Sie sich an")
    logintxt1["font"] = "Arial 10 bold"
    logintxt1.place(relx = 0.5, y = 6, anchor = "n")
    
    logintxt2 = tkinter.Label(login, text = "Benutzername:")
    logintxt2["font"] = "Arial 10"
    logintxt2.place(x = 10, y = 30, anchor = "nw")
    
    e1 = tkinter.Entry(login)
    e1.place(x = 120, y = 33, anchor = "nw")

    logintxt3 = tkinter.Label(login, text = "Passwort:")
    logintxt3["font"] = "Arial 10"
    logintxt3.place(x = 10, y = 60, anchor = "nw")
        
    e2 = tkinter.Entry(login, show = "*")
    e2.place(x = 120, y = 60, anchor = "nw")

    #Extras
    def abb():
        login.destroy()
        
    abbruch = tkinter.Button(login, text = "Abbruch", command = abb)
    abbruch.place(x = 188, y = 90, anchor = "nw")

    los = tkinter.Button(login, text = "Login", command = pwkopf)
    los.place(x = 135, y = 90, anchor = "nw")

    ver = tkinter.Label(login)
    ver.place(x = 14, y = 91)

    login.mainloop()
        
#Command für Kopfrechen-Trainer
def demain():
    head.destroy()
    hallo.destroy()
    meister.destroy()
    kopf.destroy()
    blatt.destroy()

#Haupseite
main = tkinter.Tk()
main.geometry("1000x580")
#Titelbild
head = tkinter.Label(main)
im = tkinter.PhotoImage(file="...")
head["image"] = im
head.pack()

#Begrüßungstext
hallo = tkinter.Label(main, text = """...""")
hallo.pack()
hallo["font"] = "Arial 20"

#Denn Übung macht den Meister!
meister = tkinter.Label(main, text = "Übung macht den Meister!")
meister.pack()
meister["font"] = "Arial 30"

#Button zum Kopfrechen-Trainer
kopf = tkinter.Button(main, text  = "Zum Kopfrechentrainer", command = login)
kopf["bg"] = "#14ADA0"
kopf["fg"] = "#FFFFFF"
kopf["relief"] = "flat"
kopf["height"] = 3
kopf["width"] = 29
kopf["font"] = "Arial 15 bold"
kopf.pack(padx = 70, pady = 20, side = "left")

#Button zu den Übungsblättern
blatt = tkinter.Button(main, text  = "Zu den Übungsblättern")
blatt["bg"] = "#1894CE"
blatt["fg"] = "#FFFFFF"
blatt["relief"] = "flat"
blatt["height"] = 3
blatt["width"] = 29
blatt["font"] = "Arial 15 bold"
blatt.pack(padx = 70, pady = 20, side = "right")


#Window Icon Set
main.iconbitmap("...")
main.title("Fiete Pauker")

main.mainloop()
Liebe Grüße.
Benutzeravatar
wuf
User
Beiträge: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Montag 19. Februar 2018, 11:06

Hi l30n100

Mit den Code-Tags hat es ja schon bestens geklappt. So wird das Ganze doch schon wesentlich übersichtlicher.

Vorab:
Die Suppe kann auf verschiedene arten gekocht werden. (Nobody is perfect)

Grundlegendes:
a)
Die für Tkinter wichtigsten Import abändern von:
import Tkinter
import tkinter

auf:
import Tkinter as tk
import tkinter as tk


b)
Die Zeile tkinter.Tk() bezieungsweise tk.Tk() darf im Skript nur einmal vorkommen! Für weitere Fenster steht das tk.Toplevel() Widget oder vorgefertigte Dialoge zur Verfügung.

c)
Neben dem Tellerrand (Modulebene) sollte so wenig Suppe wie möglich landen. Mit Ausnahme des Bestecks z.B. Importe, Konstanten. Abhilfe durch verwendung von Funktionen und Klassen.

d)
Scharfe Gewürze wie Importe verziert Sternchen sind zu vermeiden! (Obwohl es von vielen Buchautoren geliebt wird).

e)
Globales bewirkt meistens saures Aufstossen (z.B. Globale Variablen)

f)
Wenn möglich den Verzicht auf absolute Widgetplatzierung (keine .place(....)) Verhalten sich wie festgenagelte Objekte. Für geordnete Platzierung (.grid(...)). Für flexible dynamische Platzierung (.pack(...))

g)
Seitenformat wenn möglich im Hochformat auf 80 Zeichen pro Zeile beschränkt. Das für Python so wichtige Einrücken auf vier Leerzeichen begrenzen.

h)
Für die Gestaltung der Tischbedeckung (Skript-Editierung) gibt es einen Leitfaden der unter PEP8 Style Guide bekannt ist. Siehe:
http://gki.informatik.uni-freiburg.de/t ... guide.html

N.B.:
Sicher sind meine Erwähnungen noch nicht komplett und können jederzeit ergänzt werden. Einiges davon wurde hier im Forum schon tausendmal wiedergekäut. Gut so! Dies trägt mit der Zeit sicher zur sukzessiven Verfeinerung des angewandten bei.

Hier der erste unverbindliche Wurf (meine Suppe) für das Hauptfenster deiner Anwendung:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tkinter as tk 

TITLE = "Fiete Pauker"
TITLE_ICO = "..."
TITLE_IMAGE = "title_image.gif"
MAIN_WIN_WIDTH = 1000
MAIN_WIN_HEIGHT = 580


class MainWindowFrame(object):
    
    def __init__(self, parent):
        self.parent = parent
        
        self.frame = tk.Frame(parent.main_win)
        self.frame.pack(fill='both', expand=True)

        #Titelbild & Icon
        #parent.main_win.iconbitmap(TITLE_ICO) # Für Windows
        self.image = tk.PhotoImage(file=TITLE_IMAGE)
        tk.Label(self.frame, image=self.image).pack()

        #Begrüßungstext
        tk.Label(self.frame, text = "...", font="Arial 20").pack()

        #Denn Übung macht den Meister!
        tk.Label(self.frame, text = "Übung macht den Meister!",
            font="Arial 30").pack()

        #Rahmen für die Buttons
        button_frame = tk.Frame(self.frame)
        button_frame.pack(fill='both', expand=True)

        #Button zum Kopfrechen-Trainer
        kopf = tk.Button(button_frame, text  = "Zum Kopfrechentrainer",
            command=self.parent.login)
        kopf["bg"] = "#14ADA0"
        kopf["fg"] = "#FFFFFF"
        kopf["relief"] = "flat"
        kopf["height"] = 3
        kopf["width"] = 29
        kopf["font"] = "Arial 15 bold"
        kopf.pack(padx = 70, pady = 20, side = "left")
         
        #Button zu den Übungsblättern
        blatt = tk.Button(button_frame, text  = "Zu den Übungsblättern")
        blatt["bg"] = "#1894CE"
        blatt["fg"] = "#FFFFFF"
        blatt["relief"] = "flat"
        blatt["height"] = 3
        blatt["width"] = 29
        blatt["font"] = "Arial 15 bold"
        blatt.pack(padx = 70, pady = 20, side = "right")


class Application(object):

    def __init__(self, main_win, title):
        self.main_win = main_win
        main_win.title(title)
        
        # Schliessung des Hauptfensters übder das 'x'-Symbol in der Titelleiste
        main_win.protocol("WM_DELETE_WINDOW", self.close_app)
        # Erstelle die Geometriedaten für ein zentriertes Hauptfenster
        geometry = self.center_win(main_win, MAIN_WIN_WIDTH, MAIN_WIN_HEIGHT)
        # Zentrier das Hauptfenster
        self.main_win.geometry("{}x{}+{}+{}".format(*geometry))
        # Erstelle den Inhalt des Hauptfensters
        self.main_window_frame = MainWindowFrame(self)
    
    def login(self):
        print('Hier wird dann das Loginfenster geöffnet')
    
    def center_win(self, window, width, height):
        xpos = int((window.winfo_screenwidth() - width) / 2)
        ypos = int((window.winfo_screenheight() - height) / 2)
        return width, height, xpos, ypos

    def close_app(self):
        # Here do something before apps shutdown
        print("Good Bye!")
        self.main_win.withdraw()
        self.main_win.destroy()

    
def main():
    main_win = tk.Tk()
    app = Application(main_win, TITLE)
    main_win.mainloop()
    
main()
Versuch das Skript zu verstehen. Unser Forum mit seinen insgesamt 14977+ Mitgliedern findet auf eventuelle Fragen sicher auch Antworten.

Gruss wuf :wink:
Take it easy Mates!
l30n100
User
Beiträge: 19
Registriert: Sonntag 18. Februar 2018, 14:15

Montag 19. Februar 2018, 14:56

Hi wuf,
erst einmal vielen dank für die Tipps. :wink:
Ich werde mir das Skript noch mal in ruhe anschauen,
und es nochmal selber versuchen.
lg
l30n100
User
Beiträge: 19
Registriert: Sonntag 18. Februar 2018, 14:15

Samstag 24. Februar 2018, 22:11

wuf hat geschrieben:Hi l30n100

Mit den Code-Tags hat es ja schon bestens geklappt. So wird das Ganze doch schon wesentlich übersichtlicher.

Vorab:
Die Suppe kann auf verschiedene arten gekocht werden. (Nobody is perfect)

Grundlegendes:
a)
Die für Tkinter wichtigsten Import abändern von:
import Tkinter
import tkinter

auf:
import Tkinter as tk
import tkinter as tk


b)
Die Zeile tkinter.Tk() bezieungsweise tk.Tk() darf im Skript nur einmal vorkommen! Für weitere Fenster steht das tk.Toplevel() Widget oder vorgefertigte Dialoge zur Verfügung.

c)
Neben dem Tellerrand (Modulebene) sollte so wenig Suppe wie möglich landen. Mit Ausnahme des Bestecks z.B. Importe, Konstanten. Abhilfe durch verwendung von Funktionen und Klassen.

d)
Scharfe Gewürze wie Importe verziert Sternchen sind zu vermeiden! (Obwohl es von vielen Buchautoren geliebt wird).

e)
Globales bewirkt meistens saures Aufstossen (z.B. Globale Variablen)

f)
Wenn möglich den Verzicht auf absolute Widgetplatzierung (keine .place(....)) Verhalten sich wie festgenagelte Objekte. Für geordnete Platzierung (.grid(...)). Für flexible dynamische Platzierung (.pack(...))

g)
Seitenformat wenn möglich im Hochformat auf 80 Zeichen pro Zeile beschränkt. Das für Python so wichtige Einrücken auf vier Leerzeichen begrenzen.

h)
Für die Gestaltung der Tischbedeckung (Skript-Editierung) gibt es einen Leitfaden der unter PEP8 Style Guide bekannt ist. Siehe:
http://gki.informatik.uni-freiburg.de/t ... guide.html

N.B.:
Sicher sind meine Erwähnungen noch nicht komplett und können jederzeit ergänzt werden. Einiges davon wurde hier im Forum schon tausendmal wiedergekäut. Gut so! Dies trägt mit der Zeit sicher zur sukzessiven Verfeinerung des angewandten bei.

Hier der erste unverbindliche Wurf (meine Suppe) für das Hauptfenster deiner Anwendung:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tkinter as tk 

TITLE = "Fiete Pauker"
TITLE_ICO = "..."
TITLE_IMAGE = "title_image.gif"
MAIN_WIN_WIDTH = 1000
MAIN_WIN_HEIGHT = 580


class MainWindowFrame(object):
    
    def __init__(self, parent):
        self.parent = parent
        
        self.frame = tk.Frame(parent.main_win)
        self.frame.pack(fill='both', expand=True)

        #Titelbild & Icon
        #parent.main_win.iconbitmap(TITLE_ICO) # Für Windows
        self.image = tk.PhotoImage(file=TITLE_IMAGE)
        tk.Label(self.frame, image=self.image).pack()

        #Begrüßungstext
        tk.Label(self.frame, text = "...", font="Arial 20").pack()

        #Denn Übung macht den Meister!
        tk.Label(self.frame, text = "Übung macht den Meister!",
            font="Arial 30").pack()

        #Rahmen für die Buttons
        button_frame = tk.Frame(self.frame)
        button_frame.pack(fill='both', expand=True)

        #Button zum Kopfrechen-Trainer
        kopf = tk.Button(button_frame, text  = "Zum Kopfrechentrainer",
            command=self.parent.login)
        kopf["bg"] = "#14ADA0"
        kopf["fg"] = "#FFFFFF"
        kopf["relief"] = "flat"
        kopf["height"] = 3
        kopf["width"] = 29
        kopf["font"] = "Arial 15 bold"
        kopf.pack(padx = 70, pady = 20, side = "left")
         
        #Button zu den Übungsblättern
        blatt = tk.Button(button_frame, text  = "Zu den Übungsblättern")
        blatt["bg"] = "#1894CE"
        blatt["fg"] = "#FFFFFF"
        blatt["relief"] = "flat"
        blatt["height"] = 3
        blatt["width"] = 29
        blatt["font"] = "Arial 15 bold"
        blatt.pack(padx = 70, pady = 20, side = "right")


class Application(object):

    def __init__(self, main_win, title):
        self.main_win = main_win
        main_win.title(title)
        
        # Schliessung des Hauptfensters übder das 'x'-Symbol in der Titelleiste
        main_win.protocol("WM_DELETE_WINDOW", self.close_app)
        # Erstelle die Geometriedaten für ein zentriertes Hauptfenster
        geometry = self.center_win(main_win, MAIN_WIN_WIDTH, MAIN_WIN_HEIGHT)
        # Zentrier das Hauptfenster
        self.main_win.geometry("{}x{}+{}+{}".format(*geometry))
        # Erstelle den Inhalt des Hauptfensters
        self.main_window_frame = MainWindowFrame(self)
    
    def login(self):
        print('Hier wird dann das Loginfenster geöffnet')
    
    def center_win(self, window, width, height):
        xpos = int((window.winfo_screenwidth() - width) / 2)
        ypos = int((window.winfo_screenheight() - height) / 2)
        return width, height, xpos, ypos

    def close_app(self):
        # Here do something before apps shutdown
        print("Good Bye!")
        self.main_win.withdraw()
        self.main_win.destroy()

    
def main():
    main_win = tk.Tk()
    app = Application(main_win, TITLE)
    main_win.mainloop()
    
main()
Versuch das Skript zu verstehen. Unser Forum mit seinen insgesamt 14977+ Mitgliedern findet auf eventuelle Fragen sicher auch Antworten.

Gruss wuf :wink:
Hallo ich bin's wieder :D

Ich wollte noch einmal fragen wozu das 'object' in MainWindowFrame und Application steht.

Lg
Benutzeravatar
wuf
User
Beiträge: 1483
Registriert: Sonntag 8. Juni 2003, 09:50

Samstag 24. Februar 2018, 23:01

Hi

Das hat mit New Style Classes zu tun. Im Internet ist viel darüber zu finden z.B.:
https://realmike.org/blog/2010/07/18/in ... in-python/

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
Kebap
User
Beiträge: 401
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Sonntag 25. Februar 2018, 14:54

l30n100 hat geschrieben: Hallo ich bin's wieder :D

Ich wollte noch einmal fragen wozu das 'object' in MainWindowFrame und Application steht.
Willkommen zurück!

Das "object" hat damit zu tun, dass dort Klassen "class" definiert werden. Da kann man (muss aber nicht) in Klammer angeben, wovon die Klasse erben soll, in diesem Fall vom allgemeinen Objekt namens "object".

Eine Bitte habe ich noch: Bitte kopiere nicht den kompletten Beitrag, auf den du antworten willst, besonders wenn er direkt vor deinem steht. Das wird dann unübersichtlich, wenn man alles doppelt lesen muss.

Viel Spaß noch mit Python! :mrgreen:
MorgenGrauen: 1 Welt, >12 Gilden, >85 Abenteuer, >1000 Waffen und Rüstungen,
>2500 NPC, >16000 Räume, >170 freiwillige Programmierer, einfach Text, seit 1992.
un1e4shed
User
Beiträge: 1
Registriert: Sonntag 22. April 2018, 08:45

Sonntag 22. April 2018, 08:52

Hallo Zusammen,
ich bin auch noch recht frisch und hab daher noch so meine Probleme mit objektbezogener Programmierung sowie mit Tkinter. Beides in Kombination ist jetzt nicht so einfach....

Code: Alles auswählen

  
  def login(self):
        print('Hier wird dann das Loginfenster geöffnet')
Daher jetzt meine Frage.... Wie genau lade ich denn dann das Loginfenster? mit Toplevel()?
Oder anders gefragt, wie wechsle ich zwischen den einzelnen Frames hin und her?
Benutzeravatar
ThomasL
User
Beiträge: 291
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Montag 28. Mai 2018, 16:10

Ich denke mal, dass waren die beiden letzten Spamposts die dieser User hier verfasst hat.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
Antworten