I am creating a tkinter app and I have come across a problem that I can't solve. I have seperated each page into its own file, to make it easier in the long run as the program grows substantially. One Page
that I want to call/show requires the window to be maximised, but otherwise I want to window to be 400x400
. I cannot find a way to change the state of root = Tk()
from another file. I have provided a MVP below.
# main.py
from window import Window
myWindow = Window()
myWindow.start()
window.py
from tkinter import *
from mainView import MainView
class Window:
def __init__(self):
self.root = Tk()
self.root.title("Tkinter Window")
self.root.geometry("400x400")
self.startView = MainView(self.root)
self.startView.pack(side=TOP, fill=BOTH, expand=True)
def start(self):
self.root.mainloop()
# mainView.py
from tkinter import *
from homePage import HomePage
from firstPage import FirstPage
class MainView(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
self.mainFrame = Frame
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 (HomePage, FirstPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky=NSEW)
self.show_frame(HomePage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# homePage.py
from tkinter import *
from page import Page
from firstPage import FirstPage
class HomePage(Page):
def __init__(self, parent, controller):
Page.__init__(self, parent)
container = Frame(self)
container.pack(side=TOP,
fill=BOTH,
expand=True,
padx=8,
pady=8)
welcome = Label(container,
text="Welcome to Earl")
welcome.pack(side=TOP,
fill=BOTH,
expand=True,
padx=8,
pady=8)
container_buttons = Frame(container)
container_buttons.pack(side=TOP,
fill=BOTH,
expand=True,
padx=8,
pady=8)
container_buttons.columnconfigure(0,
weight=1)
container_buttons.columnconfigure(1,
weight=1)
for i, page in enumerate((FirstPage), 0):
if i % 2 != 0:
container_buttons.rowconfigure(int((i - 1) / 2),
weight=1)
Button(container_buttons,
text=page.name,
command=lambda p=page: controller.show_frame(p)).grid(column=1,
row=int((i - 2) / 2),
sticky=NSEW,
padx=8,
pady=8)
else:
Button(container_buttons,
text=page.name,
command=lambda p=page: controller.show_frame(p)).grid(column=0,
row=int((i - 1) / 2),
sticky=NSEW,
padx=8,
pady=8)
# firstPage.py
from tkinter import *
import homePage
from page import Page
class FirstPage(Page):
name = "First Page"
def __init__(self, parent, controller):
Page.__init__(self, parent)
container = Frame(self)
container.pack(side=TOP,
fill=BOTH,
expand=True,
padx=8,
pady=8)
container.columnconfigure(0, weight=1)
container.columnconfigure(1, weight=1)
label_title = Label(container,
text="First Page")
label_title.grid(row=0,
column=0,
columnspan=2,
sticky=NSEW)
self.entries = {}
for i, name in enumerate(("Name",
"Number of Columns",
"Number of Rows"),
1):
container.rowconfigure(i, weight=1)
label = Label(container,
text=name)
label.grid(row=i,
column=0,
sticky=EW,
padx=8,
pady=8)
entry = Entry(container)
self.entries[name] = entry
entry.grid(row=i,
column=1,
sticky=EW,
padx=8,
pady=8)
button_back = Button(container,
text="Back",
command=lambda c=controller: c.show_frame(homePage.HomePage))
button_back.grid(row=4,
column=0,
sticky=NSEW,
padx=8,
pady=8)
What I want is when you press the "First Page" button on the Home Page
I want to maximise the window. I have tried creating a changeState
function in all of the 5 files above, but ive had no luck.
My thinking was that I would have to do it through main.py
as that is the initialisation of the root
window, but I get a ImportError: cannot import name 'Window' from partially initialized module 'window'
error.
Any help/pointing me in the right direction would be greatly appreciated, if you need more info I will update this question with the needed info.
CodePudding user response:
You can get the root window for any widget with the winfo_toplevel
command. So, you should be able to use self.winfo_toplevel
inside any of your classes.
Or, since you have a controller, put a function in the controller and then call the function via the controller.