Python Forum
[Tkinter] Switch Frames
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Switch Frames
#1
Any help is appreciated. I'm trying to create main window(quiz), on click start button I want to switch the frame(pagetwo)etc.

from tkinter import *
from tkinter import messagebox
from tkinter import Tk
import sqlite3



# Creating DB - (questioner.db)
con = sqlite3.connect('questioner.db')
cur = con.cursor()

# Frames Controller
class MainFunc(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)

        container = 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 (Questionnaire, PageOne, PageTwo):

            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(Questionnaire)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()


class Questionnaire:
    def __init__(self, master, controller):

        # Main Frame
        header = Frame(master)
        header.grid(row=0, sticky='news',pady = 50, padx = 25)

        content = Frame(master)
        content.grid(row=1, sticky='N', pady = 50, padx = 25)

        footer = Frame(master)
        footer.grid(row=2, sticky='news', pady = 50, padx = 25)

        root.columnconfigure(0, weight=1) # 100% 

        root.rowconfigure(0, weight=2) # 10%
        root.rowconfigure(1, weight=7) # 80%
        root.rowconfigure(2, weight=1) # 10%


        # Student Name
        self.lbl_studetname = Label(header, text = 'Student Name: ')
        self.lbl_studetname.grid(row = 0, column = 1, sticky = W)

        self.entStudentname = Entry(header, width = 20)
        self.entStudentname.grid(row = 0, column = 2, sticky = W)

        # Student Surname
        self.lbl_studetsurname = Label(header, text = 'Student Surname: ')
        self.lbl_studetsurname.grid(row = 0, column = 3, padx = (20,0), sticky = W)

        self.entStudentsurname = Entry(header, width = 20)
        self.entStudentsurname.grid(row = 0, column = 4, sticky = W)

        # Student ID Card
        self.lbl_studetId = Label(header, text = 'Student ID card: ')
        self.lbl_studetId.grid(row = 0, column = 5, padx = (20,0), sticky = W)

        self.entStudentId = Entry(header, width = 20)
        self.entStudentId.grid(row = 0, column = 6, sticky = W)

        # Quistioner Guide
        self.lbl_guide = Label(content, text = 'Please read the questions carefully, you have 45 minutes to finish the quiz. \n Any questions regarding the quiz please raise your hand and do not disturb your colleagues!')
        self.lbl_guide.grid(row = 1, column = 2, columnspan = 4)

        # Start Button
        self.startButton = Button(content, text = 'START', padx = 20, command=lambda: controller.show_frame(PageOne))
        self.startButton.grid(row = 3, column = 4, pady = 50, sticky = W)


        # Statistic
        self.lbl_studentCounter = Label(footer, text = 'Taken:')
        self.lbl_studentCounter.grid(row = 0, column = 0, padx = 5)

        self.lbl_avgscore = Label(footer, text = 'Average Score:')
        self.lbl_avgscore.grid(row = 0, column = 1, padx = 5)

        self.lbl_lowestScore = Label(footer, text = 'Lowest Score:')
        self.lbl_lowestScore.grid(row = 0, column = 2, padx = 5)

        self.lbl_highestScore = Label(footer, text = 'Highest Score:')
        self.lbl_highestScore.grid(row = 0, column = 3, padx = 5)

# Page One
class PageOne(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller = controller

        label = Label(self, text="This is page 1")
        label.pack(side="top", fill="x", pady=10)

        button = Button(self, text="Next Page", command = lambda : controller.show_frame("PageTwo"))
        button.pack()

# Page Two
class PageTwo(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)

        self.controller = controller
        label = Label(self, text="This is page 2")
        label.pack(side="top", fill="x", pady=10)

        button = Button(self, text="Next Page", command = lambda : controller.show_frame("StartPage"))
        button.pack()       



root = Tk()
app = MainFunc(Tk)
root.title('Qustioner Quiz')
root.geometry("800x600+600+200")
root.iconbitmap('icon.ico')
root.resizable(False, False)
root.mainloop()
Reply
#2
There are times when a new class is needed and when it's not- imo there's no need for more classes. You are going to put in questions and gathering data from each page so keep it simple. There are lots of options to handle multiple pages.
1) ttk.Notebook -this creates tabs on the top, you can use buttons to scroll.
2) Use one frame and remove widgets from it with pack, place or grid_forget().
3) Create a new toplevel page that is a child of the main page.
gl

here's my rewrite that uses grid_forget() page2 and toplevel for page3 :
from tkinter import *
from random import shuffle, random, choice
from tkinter.messagebox import *
from tkinter.simpledialog import askstring
import logging, sys


logging.basicConfig(level= logging.DEBUG)
#logging.disable(logging.CRITICAL)

class Quiz_Login(Frame):
    def __init__(self, parent=None):
        self.parent= parent
        Frame.__init__(self, self.parent)
        self.pack(expand=YES, fill=BOTH)
        
        self.canvas= Canvas(self)
        self.canvas.config(width= 500, height= 700, bg='lime')
        self.canvas.pack(expand=YES, fill=BOTH)
        # Main Frame
        self.header = Frame(self.canvas)
        self.header.grid(row=0, sticky='news',pady = 50, padx = 25)
 
        self.content = Frame(self.canvas)
        self.content.grid(row=1, sticky='N', pady = 50, padx = 25)
 
        self.footer = Frame(self.canvas)
        self.footer.grid(row=2, sticky='news', pady = 50, padx = 25)
 
 
 
        # Student Name
        self.lbl_studetname = Label(self.header, text = 'Student Name: ')
        self.lbl_studetname.grid(row = 0, column = 1, sticky = W)
 
        self.entStudentname = Entry(self.header, width = 20)
        self.entStudentname.grid(row = 0, column = 2, sticky = W)
 
        # Student Surname
        self.lbl_studetsurname = Label(self.header, text = 'Student Surname: ')
        self.lbl_studetsurname.grid(row = 0, column = 3, padx = (20,0), sticky = W)
 
        self.entStudentsurname = Entry(self.header, width = 20)
        self.entStudentsurname.grid(row = 0, column = 4, sticky = W)
 
        # Student ID Card
        self.lbl_studetId = Label(self.header, text = 'Student ID card: ')
        self.lbl_studetId.grid(row = 0, column = 5, padx = (20,0), sticky = W)
 
        self.entStudentId = Entry(self.header, width = 20)
        self.entStudentId.grid(row = 0, column = 6, sticky = W)
 
        # Quistioner Guide
        self.lbl_guide = Label(self.content, text = 'Please read the questions carefully, you have 45 minutes to finish the quiz. \n Any questions regarding the quiz please raise your hand and do not disturb your colleagues!')
        self.lbl_guide.grid(row = 1, column = 2, columnspan = 4)
 
        # Start Button
        self.startButton = Button(self.content, text = 'START', padx = 20,
                                  command=self.page_one)
        self.startButton.grid(row = 3, column = 4, pady = 50, sticky = W)
 
 
        # Statistic
        self.lbl_studentCounter = Label(self.footer, text = 'Taken:')
        self.lbl_studentCounter.grid(row = 0, column = 0, padx = 5)
 
        self.lbl_avgscore = Label(self.footer, text = 'Average Score:')
        self.lbl_avgscore.grid(row = 0, column = 1, padx = 5)
 
        self.lbl_lowestScore = Label(self.footer, text = 'Lowest Score:')
        self.lbl_lowestScore.grid(row = 0, column = 2, padx = 5)
 
        self.lbl_highestScore = Label(self.footer, text = 'Highest Score:')
        self.lbl_highestScore.grid(row = 0, column = 3, padx = 5)
 

        
        
        self.bind_all('<Key>', self.key)
        self.g_count=0
    def page_one(self):
        self.header.grid_forget()
        self.content.grid_forget()
        self.footer.grid_forget()
        self.page_one_frm= Frame(self.canvas,width=700,height=600)
        self.page_one_frm.place(x=10,y=10)
        
        label = Label(self.page_one_frm, text="This is page 1")
        label.place(x=20,y=20)
 
        button = Button(self.page_one_frm, text="Next Page",
                        command = self.page_two)
        button.place(x=20,y=70)
    def page_two(self):
        
        self.top2= Toplevel()
        self.top2.title('Page one')
        
        self.canvas3= Canvas(self.top2)
        self.canvas3.config(width=700,height=500,bg='yellow')
        self.canvas3.pack(expand='yes',fill='both')
        label = Label(self.canvas3, text="This is page 2")
        label.place(x=20,y=20)
 
        button = Button(self.canvas3, text="Next Page",
                        command = self.page_three)
        button.place(x=20,y=70)
    def page_three(self):
        pass
    def key(self, event):
        self.g_count +=1
        message= 'count:{0} key:{1} num:{2} state:{3}'.format(self.g_count,
                                                 event.keysym,event.keysym_num,
                                       event.state)
        logging.debug(message)
        
    def get_entry(self):
        pass
if __name__ == '__main__':
    root= Tk()
    Quiz_Login(root)
    root.mainloop()
Maryan likes this post
Reply
#3
I will definitely take a look at ttk.notebook, its great idea. On my project, I forgot on grid_forget() function.
I found a weird solution, it's kind of overlay on the frames, but it works. I appreciate your help!


(Oct-24-2020, 10:08 PM)joe_momma Wrote: There are times when a new class is needed and when it's not- imo there's no need for more classes. You are going to put in questions and gathering data from each page so keep it simple. There are lots of options to handle multiple pages.
1) ttk.Notebook -this creates tabs on the top, you can use buttons to scroll.
2) Use one frame and remove widgets from it with pack, place or grid_forget().
3) Create a new toplevel page that is a child of the main page.
gl

here's my rewrite that uses grid_forget() page2 and toplevel for page3 :
from tkinter import *
from random import shuffle, random, choice
from tkinter.messagebox import *
from tkinter.simpledialog import askstring
import logging, sys


logging.basicConfig(level= logging.DEBUG)
#logging.disable(logging.CRITICAL)

class Quiz_Login(Frame):
    def __init__(self, parent=None):
        self.parent= parent
        Frame.__init__(self, self.parent)
        self.pack(expand=YES, fill=BOTH)
        
        self.canvas= Canvas(self)
        self.canvas.config(width= 500, height= 700, bg='lime')
        self.canvas.pack(expand=YES, fill=BOTH)
        # Main Frame
        self.header = Frame(self.canvas)
        self.header.grid(row=0, sticky='news',pady = 50, padx = 25)
 
        self.content = Frame(self.canvas)
        self.content.grid(row=1, sticky='N', pady = 50, padx = 25)
 
        self.footer = Frame(self.canvas)
        self.footer.grid(row=2, sticky='news', pady = 50, padx = 25)
 
 
 
        # Student Name
        self.lbl_studetname = Label(self.header, text = 'Student Name: ')
        self.lbl_studetname.grid(row = 0, column = 1, sticky = W)
 
        self.entStudentname = Entry(self.header, width = 20)
        self.entStudentname.grid(row = 0, column = 2, sticky = W)
 
        # Student Surname
        self.lbl_studetsurname = Label(self.header, text = 'Student Surname: ')
        self.lbl_studetsurname.grid(row = 0, column = 3, padx = (20,0), sticky = W)
 
        self.entStudentsurname = Entry(self.header, width = 20)
        self.entStudentsurname.grid(row = 0, column = 4, sticky = W)
 
        # Student ID Card
        self.lbl_studetId = Label(self.header, text = 'Student ID card: ')
        self.lbl_studetId.grid(row = 0, column = 5, padx = (20,0), sticky = W)
 
        self.entStudentId = Entry(self.header, width = 20)
        self.entStudentId.grid(row = 0, column = 6, sticky = W)
 
        # Quistioner Guide
        self.lbl_guide = Label(self.content, text = 'Please read the questions carefully, you have 45 minutes to finish the quiz. \n Any questions regarding the quiz please raise your hand and do not disturb your colleagues!')
        self.lbl_guide.grid(row = 1, column = 2, columnspan = 4)
 
        # Start Button
        self.startButton = Button(self.content, text = 'START', padx = 20,
                                  command=self.page_one)
        self.startButton.grid(row = 3, column = 4, pady = 50, sticky = W)
 
 
        # Statistic
        self.lbl_studentCounter = Label(self.footer, text = 'Taken:')
        self.lbl_studentCounter.grid(row = 0, column = 0, padx = 5)
 
        self.lbl_avgscore = Label(self.footer, text = 'Average Score:')
        self.lbl_avgscore.grid(row = 0, column = 1, padx = 5)
 
        self.lbl_lowestScore = Label(self.footer, text = 'Lowest Score:')
        self.lbl_lowestScore.grid(row = 0, column = 2, padx = 5)
 
        self.lbl_highestScore = Label(self.footer, text = 'Highest Score:')
        self.lbl_highestScore.grid(row = 0, column = 3, padx = 5)
 

        
        
        self.bind_all('<Key>', self.key)
        self.g_count=0
    def page_one(self):
        self.header.grid_forget()
        self.content.grid_forget()
        self.footer.grid_forget()
        self.page_one_frm= Frame(self.canvas,width=700,height=600)
        self.page_one_frm.place(x=10,y=10)
        
        label = Label(self.page_one_frm, text="This is page 1")
        label.place(x=20,y=20)
 
        button = Button(self.page_one_frm, text="Next Page",
                        command = self.page_two)
        button.place(x=20,y=70)
    def page_two(self):
        
        self.top2= Toplevel()
        self.top2.title('Page one')
        
        self.canvas3= Canvas(self.top2)
        self.canvas3.config(width=700,height=500,bg='yellow')
        self.canvas3.pack(expand='yes',fill='both')
        label = Label(self.canvas3, text="This is page 2")
        label.place(x=20,y=20)
 
        button = Button(self.canvas3, text="Next Page",
                        command = self.page_three)
        button.place(x=20,y=70)
    def page_three(self):
        pass
    def key(self, event):
        self.g_count +=1
        message= 'count:{0} key:{1} num:{2} state:{3}'.format(self.g_count,
                                                 event.keysym,event.keysym_num,
                                       event.state)
        logging.debug(message)
        
    def get_entry(self):
        pass
if __name__ == '__main__':
    root= Tk()
    Quiz_Login(root)
    root.mainloop()
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020