简体   繁体   中英

Tkinter: Create non overlapping frames

I am working on creating a login screen with a change password screen, and I have encountered a problem with the two screens overlapping each other.

import fileinput
import tkinter as tk
import tkinter.messagebox as tm
from tkinter import ttk

class TypingLogin(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        container=tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (LoginScreen,TestScreen):
            frame=F(container, self)
            self.frames[F]=frame
        self.ShowFrame(LoginScreen)


    def ShowFrame(self, cont):
        frame=self.frames[cont]
        frame.tkraise()

class LoginScreen(tk.Frame):

    def __init__(self, parent, controller):
        self.controller=controller
        self.parent=parent
        tk.Frame.__init__(self, parent)

        w = 270
        h = 170
        x = 500
        y = 100
        controller.geometry("%dx%d+%d+%d" % (w, h, x, y))

        self.canvas=tk.Frame(parent, bg="red")
        self.canvas.pack(side='top',fill='both',expand='yes')

        self.passwordlabel=tk.Label(self.canvas, text="Password")
        self.passwordentry=tk.Entry(self.canvas, show="*")

        self.passwordlabel.place(x=40, y=60)
        self.passwordentry.place(x=100, y=60)

        self.loginbutton=tk.Button(self.canvas, text="Change Password",  command=self.ChangeButtonClicked)
        self.loginbutton2=tk.Button(self.canvas, text="Login")#When Lesson select screen is made, put navigating command here

        self.loginbutton.place(x=80, y=120)
        self.loginbutton2.place(x=110, y=90)

        self.usernamelabel=tk.Label(self.canvas, text="Username")
        self.usernameentry=ttk.Combobox(self.canvas)
        self.usernameentry.bind("<<ComboboxSelected>>")
        self.usernameentry['values']=(combol)
        self.usernameentry.current(0)
        self.usernamelabel.place(x=35, y=30)
        self.usernameentry.place(x=100, y=30)

    def ChangeButtonClicked(self):
        global username, passWord, codedPassWord

        username=self.usernameentry.get()
        passWord=self.passwordentry.get()
        codedPassWord = CodeWord(passWord)

        allUsers = LoadListFromFile()

        isFound = False
        for name,password in allUsers:
            if name == username:
                if codedPassWord == password:
                    isFound = True

        if isFound:
            self.controller.ShowFrame(TestScreen)
        else:
            tm.showerror("Login error", "Incorrect Login details")

class TestScreen(tk.Frame,tk.Toplevel):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        w = 270
        h = 170
        x = 500
        y = 100
        controller.geometry("%dx%d+%d+%d" % (w, h, x, y))

        self.canvas=tk.Frame(parent, bg="blue")
        self.canvas.pack(side='top',fill='both',expand='yes')

        self.label=tk.Label(self, text="Old Password")
        self.label2=tk.Label(self, text="New Password")
        self.label3=tk.Label(self, text="Confirm Password")

        self.entry=tk.Entry(self, show="*")
        self.entry2=tk.Entry(self, show="*")
        self.entry3=tk.Entry(self, show="*")

        self.label.place(x=40, y=25)
        self.label2.place(x=40, y=50)
        self.label3.place(x=40, y=75)
        self.entry.place(x=100, y=25)
        self.entry2.place(x=100, y=50)
        self.entry3.place(x=100, y=75)

        self.changebutton=tk.Button(self, text="Change")
        self.changebutton.place(x=70, y=100)

combol=['Select your name']
for e,f in my:
    combol.append(e)

app = TypingLogin()
app.title("CLHS Typing Program")
app.mainloop()

I feel like I am missing something pretty simple. I have been working on this for long enough that I am probably skimming right where the problem is. A fresh pair of eyes would be really helpful here.

Edit: The buttons "Login" and "Change Password" are there, they are just underneath the overlapping screen/frame. Just expand the window up or down to uncover them.

The first problem is that you are putting the canvas in the wrong window. Everything within a screen needs to be a child of that screen or child of a descendant.

You need to change this:

self.canvas = tk.Frame(parent, ...)

to this:

self.canvas = tk.Frame(self, ...)

You then need to make sure to place all of the screens in the main window. Do this by calling grid within the loop that creates the screens:

for F in (LoginScreen,TestScreen):
    ...
    frame.grid(row=0, column=0, sticky="nsew")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM