I am writing a program which should:
#!/usr/bin/env python
import Tkinter as tk
from Tkinter import *
class windowclass():
def __init__(self,master):
self.master = master
self.frame = tk.Frame(master)
self.lbl = Label(master , text = "Label")
self.lbl.pack()
self.btn = Button(master , text = "Button" , command = self.command )
self.btn.pack()
self.frame.pack()
def command(self):
print 'Button is pressed!'
self.newWindow = tk.Toplevel(self.master)
self.app = windowclass1(self.newWindow)
class windowclass1():
def __init__(self , master):
self.master = master
self.frame = tk.Frame(master)
master.title("a")
self.quitButton = tk.Button(self.frame, text = 'Quit', width = 25 , command = self.close_window)
self.quitButton.pack()
self.frame.pack()
def close_window(self):
self.master.destroy()
root = Tk()
root.title("window")
root.geometry("350x50")
cls = windowclass(root)
root.mainloop()
What you could do is copy the code from tkinter.py
into a file called mytkinter.py
, then do this code:
import tkinter, mytkinter
root = tkinter.Tk()
window = mytkinter.Tk()
button = mytkinter.Button(window, text="Search", width = 7,
command=cmd)
button2 = tkinter.Button(root, text="Search", width = 7,
command=cmdtwo)
And you have two windows which don't collide!
You need to specify the master for the second button. Otherwise it will get packed onto the first window. This is needed not only for Button
, but also for other widgets and non-gui objects such as StringVar
.
Quick fix: add the frame new
as the first argument to your Button
in Demo2
.
Possibly better: Currently you have Demo2
inheriting from tk.Frame
but I think this makes more sense if you change Demo2
to be something like this,
class Demo2(tk.Toplevel):
def __init__(self):
tk.Toplevel.__init__(self)
self.title("Demo 2")
self.button = tk.Button(self, text="Button 2", # specified self as master
width=25, command=self.close_window)
self.button.pack()
def close_window(self):
self.destroy()
Just as a suggestion, you should only import tkinter
once. Pick one of your first two import statements.
I rewrote your code in a more organized, better-practiced way:
import tkinter as tk
class Demo1:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.button1 = tk.Button(self.frame, text = 'New Window', width = 25, command = self.new_window)
self.button1.pack()
self.frame.pack()
def new_window(self):
self.newWindow = tk.Toplevel(self.master)
self.app = Demo2(self.newWindow)
class Demo2:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.quitButton = tk.Button(self.frame, text = 'Quit', width = 25, command = self.close_windows)
self.quitButton.pack()
self.frame.pack()
def close_windows(self):
self.master.destroy()
def main():
root = tk.Tk()
app = Demo1(root)
root.mainloop()
if __name__ == '__main__':
main()
Result:
I tried to use more than two windows using the Rushy Panchal example above. The intent was to have the change to call more windows with different widgets in them. The butnew function creates different buttons to open different windows. You pass as argument the name of the class containing the window (the second argument is nt necessary, I put it there just to test a possible use. It could be interesting to inherit from another window the widgets in common.
import tkinter as tk
class Demo1:
def __init__(self, master):
self.master = master
self.master.geometry("400x400")
self.frame = tk.Frame(self.master)
self.butnew("Window 1", "ONE", Demo2)
self.butnew("Window 2", "TWO", Demo3)
self.frame.pack()
def butnew(self, text, number, _class):
tk.Button(self.frame, text = text, width = 25, command = lambda: self.new_window(number, _class)).pack()
def new_window(self, number, _class):
self.newWindow = tk.Toplevel(self.master)
_class(self.newWindow, number)
class Demo2:
def __init__(self, master, number):
self.master = master
self.master.geometry("400x400+400+400")
self.frame = tk.Frame(self.master)
self.quitButton = tk.Button(self.frame, text = 'Quit', width = 25, command = self.close_windows)
self.label = tk.Label(master, text=f"this is window number {number}")
self.label.pack()
self.quitButton.pack()
self.frame.pack()
def close_windows(self):
self.master.destroy()
class Demo3:
def __init__(self, master, number):
self.master = master
self.master.geometry("400x400+400+400")
self.frame = tk.Frame(self.master)
self.quitButton = tk.Button(self.frame, text = 'Quit', width = 25, command = self.close_windows)
self.label = tk.Label(master, text=f"this is window number {number}")
self.label.pack()
self.label2 = tk.Label(master, text="THIS IS HERE TO DIFFERENTIATE THIS WINDOW")
self.label2.pack()
self.quitButton.pack()
self.frame.pack()
def close_windows(self):
self.master.destroy()
def main():
root = tk.Tk()
app = Demo1(root)
root.mainloop()
if __name__ == '__main__':
main()
To avoid having the chance to press multiple times the button having multiple windows... that are the same window, I made this script (take a look at this page too)
import tkinter as tk
def new_window1():
global win1
try:
if win1.state() == "normal": win1.focus()
except:
win1 = tk.Toplevel()
win1.geometry("300x300+500+200")
win1["bg"] = "navy"
lb = tk.Label(win1, text="Hello")
lb.pack()
win = tk.Tk()
win.geometry("200x200+200+100")
button = tk.Button(win, text="Open new Window")
button['command'] = new_window1
button.pack()
win.mainloop()