How to limit the number of TopLevel Window Python Tkinter - python

This is my code.
When i press CTRL+S it popups a TopLevel Window. However, when i press CTRL+S again, it popups up another window on top of it and so on.
How can i improve the code so that only one window Pops up when I press CTRL+S.
from tkinter import *
from tkinter import messagebox
class MainWindow(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.master.title("Tournament Software")
self.menu()
def menu(self):
menu = Menu(self.master)
self.master.config(menu=menu)
participant = Menu(menu, tearoff=False)
participant.add_command(label="Add participant", accelerator="Ctrl+S", command=self.addparticipant_window)
menu.add_cascade(label="Participants", menu=participant)
self.bind_all('<Control-s>', lambda e: menu.after(100,self.addparticipant_window))
def addparticipant_window(self):
participantWindow = Toplevel()
participantWindow.geometry("400x350")
participantWindow.resizable(False, False)
top_frame = Frame(participantWindow, bg='cyan', width=450, height=50, pady=3)
top_frame.grid(row=0, sticky="ew")
root = Tk()
root.iconbitmap("Icon.ico")
root.geometry("500x400")
root.resizable(False, False)
app = MainWindow(root)
root.mainloop()
Thankyou, I am new to this so help me.

from tkinter import *
from tkinter import messagebox
class MainWindow(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.master.title("Tournament Software")
self.menu()
self.popup = None
def open_up(self):
if self.popup is None or not self.popup.top.winfo_exists():
self.popup = addparticipant_window()
else:
self.popup.top.lift(self.master)
def menu(self):
menu = Menu(self.master)
self.master.config(menu=menu)
participant = Menu(menu, tearoff=False)
participant.add_command(label="Add participant", accelerator="Ctrl+S", command=self.open_up)
menu.add_cascade(label="Participants", menu=participant)
self.bind_all('<Control-s>', lambda e: menu.after(100,self.open_up))
class addparticipant_window:
def __init__(self):
self.top = Toplevel()
self.top.geometry("400x350")
self.top.resizable(False, False)
top_frame = Frame(self.top, bg='cyan', width=450, height=50, pady=3)
top_frame.grid(row=0, sticky="ew")
root = Tk()
root.geometry("500x400")
root.resizable(False, False)
app = MainWindow(root)
root.mainloop()

Related

Tkinter reference methods and variables between classes

I am stuck at referencing methods and variables between classes in Tkinter.
Here is an simple example, I have three different types of windows, which I would like to put into different classes.
In the root window, I can click the button to open the second window, where I can input something in to the Text widget.
Also in the 2nd window I want the OK button to read the content in the Text widget and insert the content into another Text widget into the 3rd window. And the Cancel button can close the 2nd window and show the root window again.
There is many bugs in the code, because I couldn't figure out how to make cross references between classes to access the methods and variables.
Could anyone help me to accomplish that? Thanks.
from tkinter import *
from tkinter import scrolledtext
def main():
"""The main app function"""
root = Tk()
root_window = Root(root)
return None
class Root:
def __init__(self, root):
# Main root window configration
self.root = root
self.root.geometry("200x100")
self.btn_ok = Button(self.root, text="Open new window",
command=NewWindow)
self.btn_ok.pack(padx=10, pady=10)
def hide(self):
"""Hide the root window."""
self.root.withdraw()
def show(self):
"""Show the root window from the hide status"""
self.root.update()
self.root.deiconify()
def onClosing(self, window):
window.destroy()
self.show()
class NewWindow:
def __init__(self):
Root.hide()
self.new_window = Toplevel()
lbl = Label(self.new_window, text="Input here:")
lbl.pack(padx=10, pady=(10, 0), anchor=W)
# Create a scrolledtext widget.
self.new_content = scrolledtext.ScrolledText(
self.new_window, wrap=WORD,
)
self.new_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
# Respond to the 'Cancel' button.
btn_cancel = Button(self.new_window, text="Cancel", width=10,
command=lambda: Root.onClosing(self.new_window))
btn_cancel.pack(padx=10, pady=10, side=RIGHT)
# Add 'OK' button to read sequence
self.btn_ok = Button(self.new_window, text="OK", width=10,
command=WorkingWindow)
self.btn_ok.pack(padx=10, pady=10, side=RIGHT)
def readContent(self):
self.content = self.new_content.get(1.0, END)
self.new_window.destroy()
workwindow = WorkingWindow()
class WorkingWindow:
def __init__(self):
self.work_window = Toplevel()
self.work_content = scrolledtext.ScrolledText(self.work_window, wrap=WORD, font=("Courier New", 11))
self.work_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
self.work_content.insert(1.0, Root.content)
if __name__ == '__main__':
main()
You were almost there all you have to do is pass the instance of Root class to other class you are calling
Here is the corrected code:
from tkinter import *
from tkinter import scrolledtext
def main():
"""The main app function"""
root = Tk()
root_window = Root(root)
root.mainloop()
class Root:
def __init__(self, root):
# Main root window configration
self.root = root
self.root.geometry("200x100")
self.btn_ok = Button(self.root, text="Open new window",
command=lambda :NewWindow(self))
self.btn_ok.pack(padx=10, pady=10)
def hide(self):
"""Hide the root window."""
self.root.withdraw()
def show(self):
"""Show the root window from the hide status"""
self.root.update()
self.root.deiconify()
def onClosing(self, window):
window.destroy()
self.show()
class NewWindow:
def __init__(self, parent):
parent.hide()
self.new_window = Toplevel()
lbl = Label(self.new_window, text="Input here:")
lbl.pack(padx=10, pady=(10, 0), anchor=W)
# Create a scrolledtext widget.
self.new_content = scrolledtext.ScrolledText(
self.new_window, wrap=WORD,
)
self.new_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
# Respond to the 'Cancel' button.
btn_cancel = Button(self.new_window, text="Cancel", width=10,
command=lambda: parent.onClosing(self.new_window))
btn_cancel.pack(padx=10, pady=10, side=RIGHT)
# Add 'OK' button to read sequence
self.btn_ok = Button(self.new_window, text="OK", width=10,
command=self.readContent)
self.btn_ok.pack(padx=10, pady=10, side=RIGHT)
def readContent(self):
self.content = self.new_content.get(1.0, END)
self.new_window.destroy()
workwindow = WorkingWindow(self)
class WorkingWindow:
def __init__(self, parent):
self.work_window = Toplevel()
self.work_content = scrolledtext.ScrolledText(self.work_window, wrap=WORD, font=("Courier New", 11))
self.work_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
self.work_content.insert(1.0, parent.content)
if __name__ == '__main__':
main()

Edit/add Tkinter widget in one Tkinter class from another Tkinter class

Suppose I have two tkinter classes which act as separate windows. How could I edit any given widget from one class in the other tkinter class. ALso, how could I add a widget in one tkinter class from the other tkinter class?
from tkinter import Tk, Label, Button
class MyFirstGUI:
def __init__(self, master):
self.master = master
master.title("A simple GUI")
self.label = Label(master, text="This is
our first GUI!")
self.label.pack()
self.greet_button = Button(master,
text="Greet", command=self.greet)
self.greet_button.pack()
self.close_button = Button(master,
text="Close", command=master.quit)
self.close_button.pack()
def greet(self):
print("Greetings!")
root = Tk()
my_gui = MyFirstGUI(root)
root.mainloop()
from tkinter import Tk, Label, Button
class MyFirstGUI2:
def __init__(self, master):
self.master = master
master.title("A simple GUI")
self.label = Label(master, text="This is
our first GUI!")
self.label.pack()
self.greet_button = Button(master,
text="Greet", command=self.greet)
self.greet_button.pack()
self.close_button = Button(master,
text="Close", command=master.quit)
self.close_button.pack()
def greet(self):
print("Greetings!")
root = Tk()
my_gui = MyFirstGUI2(root)
root.mainloop()
I think it would be better to use a Toplevel widget for your two windows (or at least one of them). Right now your first window will be created and the code will stop when it gets to the root.mainloop() line. The second window will not be created until you close the first one.
And you can pass in a reference from each class.
import tkinter
from tkinter import Tk, Label, Toplevel, Button
class MainWidget:
def __init__(self, master):
self.master = master
self.widgetTwo = None
self.label = Label(self.master, text='Widget One')
self.label.pack()
class WidgetTwo(Toplevel):
def __init__(self, master, mainWidget):
Toplevel.__init__(self, master)
self.master = master
self.mainWidget = mainWidget
self.labelTwo = Label(self, text='Widget Two')
self.labelTwo.pack()
Button(self, text='Change Main Widget Text', command=self.ChangeMainWidgetLabel).pack()
def ChangeMainWidgetLabel(self):
self.mainWidget.label.config(text='Widget One text changed')
mw = Tk()
mainWidget = MainWidget(mw)
widgetTwo = WidgetTwo(mw, mainWidget)
mainWidget.widgetTwo = widgetTwo
mw.mainloop()

changing a tkinter button color by pressing another button

I want to change the background color of Button2 by pressing Button1. Here is what I do:
from Tkinter import *
class Application():
def __init__(self, root):
self.root = root
self.Frame = Frame(self.root)
self.Frame.pack()
self.Button1 = Button(self.Frame, text = "Button 1", command = self.button1_press)
self.Button1.pack()
self.Button2 = Button(self.Frame, text = "Button 2")
self.Button2.pack()
def button1_press(self):
self.Button2.config(bg = "red")
root = Tk()
app = Application(root)
root.mainloop()
But pressing Button 1 does nothing. Any help?

How can I close the tkinter button window after use?

from tkinter import *
master = Tk()
def managerMode():
print ("Connecting to Manager Mode... please wait")
def employeeMode():
print ("Connecting to Employee Mode... please wait")
b = Button(master, text="Manager Mode", command = managerMode)
b.pack()
c = Button(master,text="Employee Mode", command=employeeMode)
c.pack()
mainloop()
This is my code, and I am planning to close window that contains the types of mode when the user picks one of those options, "Manager Mode" or "Employee Mode". How can I continue closing the button window?
Use the destroy method.
import tkinter
from tkinter import ttk
class MyApp:
def __init__(self):
self.root = tkinter.Tk()
def startman(self):
self.root.destroy() # like this
self.root = tkinter.Tk()
self.root.title('Manager Mode')
self.backbutton = ttk.Button(self.root, text='Back', command=self.startmenu)
self.backbutton.grid(column=0, row=0, sticky='nsew')
self.root.mainloop()
def startemp(self):
self.root.destroy() # or this
self.root = tkinter.Tk()
self.root.title('Employee Mode')
self.backbutton = ttk.Button(self.root, text='Back', command=self.startmenu)
self.backbutton.grid(column=0, row=0, sticky='nsew')
self.root.mainloop()
def startmenu(self):
self.root.destroy() # or this
self.root = tkinter.Tk()
self.root.title('Mode Selection')
self.manbutton = ttk.Button(self.root, text='Manager Mode', command=self.startman)
self.empbutton = ttk.Button(self.root, text='Employee Mode', command=self.startemp)
self.manbutton.grid(column=0, row=0, sticky='nsew')
self.empbutton.grid(column=0, row=1, sticky='nsew')
self.root.mainloop()
def run(self):
self.startmenu()
MyApp().run()

How to close a current window and open a new window at the same time?

This code opens a button, which links to another button. The other button can close its self, but the first button can't close itself and open a new one at the same time, How do I fix this?
import tkinter as tk
class Demo1:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.HelloButton = tk.Button(self.frame, text = 'Hello', width = 25, command = self.new_window,)
self.HelloButton.pack()
self.frame.pack()
def close_windows(self):
self.master.destroy()
self.new_window
def new_window(self):
self.new_window = tk.Toplevel(self.master)
self.app = Demo2(self.new_window)
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()
Try redefine your Demo1.new_window() as below:
def new_window(self):
self.master.destroy() # close the current window
self.master = tk.Tk() # create another Tk instance
self.app = Demo2(self.master) # create Demo2 window
self.master.mainloop()
Try this:
import tkinter as tk
class windowclass():
def __init__(self, master):
self.master = master
self.btn = tk.Button(master, text="Button", command=self.command)
self.btn.pack()
def command(self):
self.master.withdraw()
toplevel = tk.Toplevel(self.master)
toplevel.geometry("350x350")
app = Demo2(toplevel)
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()
root = tk.Tk()
root.title("window")
root.geometry("350x350")
cls = windowclass(root)
root.mainloop()
Or maybe sometimes, you want to do something else, you can hide it.
def __init__(self, parent):
self.root = parent
self.root.title("Main")
self.frame = Tk.Frame(parent)
self.frame.pack()
btn = Tk.Button(self.frame, text="New", command=self.openFrame)
btn.pack()
def hide(self):
self.root.withdraw()
def openFrame(self):
self.hide()
otherFrame = Tk.Toplevel()
otherFrame.geometry("400x300")
handler = lambda: self.CloseOtherFrame(otherFrame)
btn = Tk.Button(otherFrame, text="Close", command=handler)
btn.pack()
def CloseOtherFrame(self, otherFrame):
otherFrame.destroy()
self.show()

Categories

Resources