I'm new to Python. Trying to create two modules (.py files) which can be navigated to & fro, without having to create two windows. So, 1st module will have window & frame 1, 2nd module will have just a frame 2. On button click, the frame shown should be switched. Not sure if the below is the right way to do it, but I'm almost there. If there's a better way to do this, please suggest. testnew.py -
from tkinter import *
from functools import partial
BLACK = "#000000"
WHITE = "#FFFFFF"
class main():
def __init__(self, master):
self.frame1 = Frame(master)
self.frame1.pack()
self.label = Label(self.frame1, bg=WHITE, text="This is 1st frame.")
self.label.pack()
self.btn_1 = Button(self.frame1, bg=WHITE, text="Switch to 2nd frame",
command=partial(self.switch_to_second, master))
self.btn_1.pack()
def switch_to_second(self, master):
self.btn_1.pack_forget()
self.label.pack_forget()
self.frame1.pack_forget()
from testnew_2 import second_frame
self.secondframe = second_frame(master)
root = Tk()
root.title("Hello world")
root.geometry("500x500")
main_frame = main(root)
root.mainloop()
testnew_2.py -
from tkinter import *
from functools import partial
BLACK = "#000000"
WHITE = "#FFFFFF"
class second_frame():
def __init__(self, master):
self.frame2 = Frame(master)
self.frame2.pack()
self.label2 = Label(self.frame2, bg=BLACK, fg=WHITE, text="This is second frame.")
self.label2.pack()
self.btn_2 = Button(self.frame2, bg=BLACK, fg=WHITE, text="Switch to 1st frame",
command=partial(self.switch_to_first, master))
self.btn_2.pack()
def switch_to_first(self, master):
self.btn_2.pack_forget()
self.label2.pack_forget()
self.frame2.pack_forget()
from testnew import main
self.mainframe = main(master)
Running into a problem of another window being created this error -
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\Admin\PycharmProjects\helloworld\testnew_2.py", line 25, in switch_to_first
self.mainframe = main(master)
^^^^^^^^^^^^
File "C:\Users\Admin\PycharmProjects\helloworld\testnew.py", line 10, in __init__
self.frame1 = Frame(master)
^^^^^^^^^^^^^
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 3180, in __init__
Widget.__init__(self, master, 'frame', cnf, {}, extra)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 2628, in __init__
self.tk.call(
_tkinter.TclError: can't invoke "frame" command: application has been destroyed
CodePudding user response:
When testnew
is imported inside switch_to_first()
, the following code inside testnew.py
will be executed again to create another instance of Tk()
:
root = Tk()
root.title("Hello world")
root.geometry("500x500")
main_frame = main(root)
root.mainloop()
So there will be two windows shown. The mentioned exception will be raised when the two windows are closed.
You need to change the above code block as below:
if __name__ == "__main__":
root = Tk()
root.title("Hello world")
root.geometry("500x500")
main_frame = main(root)
root.mainloop()
Then when testnew
is imported again, no new window will be created because code inside the if block will not be executed.