Tkinter reference methods and variables between classes - python

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()

Related

I need to modify the tkinter triple button click counter code

Okay, I made a little tkinter program that basically counts how many times the button was clicked and implemented the triple button module so that it counts every third click, but I wanted to change it up so that the button instead of saying "Click me!", displays the number of clicks itself.
import tkinter as tk
class Main():
def __init__(self, root):
self.root = root
self.count = 0
frame = tk.Frame(self.root)
frame.pack()
label = tk.Label(root, text="Super click counter!", font=('Arial', 18))
label.pack(padx=20, pady=20)
btn = tk.Button(frame, text ='Click me!')
btn.pack()
btn.bind('<Triple-Button>', self.click)
self.label = tk.Label(frame, text = 'The button was clicked 0 times.')
self.label.pack()
def click(self, event):
self.count += 1
self.label.config(text=f'The button was clicked {self.count} times.')
if __name__=="__main__":
root = tk.Tk()
root.geometry("300x150")
root.title("A serious video game.")
Main(root)
root.mainloop()
we add the btn property by using self.btn = then we change the text inside it when the button is clicked 3 times using self.btn.config(text=self.count.__str__())
import tkinter as tk
class Main():
def __init__(self, root):
self.root = root
self.count = 0
frame = tk.Frame(self.root)
frame.pack()
label = tk.Label(root, text="Super click counter!", font=('Arial', 18))
label.pack(padx=20, pady=20)
self.btn = tk.Button(frame, text ='Click me!')
self.btn.pack()
self.btn.bind('<Triple-Button>', self.click)
self.label = tk.Label(frame, text = 'The button was clicked 0 times.')
self.label.pack()
def click(self, event):
self.count += 1
self.label.config(text=f'The button was clicked {self.count} times.')
self.btn.config(text=self.count.__str__())

Closing current window when opening a new window in tkinter python

I have created a program in Python using tkinter. I have created two seperate classes for two windows. I am opening the other window by clicking on the button of one window. I want it such that when new window opens the other should close. My code is
from tkinter import Tk, Toplevel
from tkinter import *
def main():
main_window = Tk()
app = first(main_window)
main_window.mainloop()
class first:
def __init__(self, root):
self.root = root
self.root.title('First window')
self.root.geometry('1350x700+0+0')
frame1 = Frame(self.root, bg='black')
frame1.place(x=400, y=50, width=400, height=600)
btn_1 = Button(frame1, command=self.second_window, text='open second window', font=("Times New Roman", 15, 'bold'), bd=3,
relief=RIDGE,
cursor='hand2', bg='red', fg='white', activeforeground='white', activebackground='red')
btn_1.place(x=100, y=350, width=220, height=35)
def second_window(self):
self.new_window = Toplevel(self.root)
self.app = second(self.new_window)
class second:
def __init__(self, root):
self.root = root
self.root.title('Second Window')
self.root.geometry("1350x700+0+0")
self.root.config(bg='white')
frame1 = Frame(self.root, bg='black')
frame1.place(x=400, y=50, width=400, height=600)
btn_1 = Button(frame1, command=self.first_window, text='open first window',
font=("Times New Roman", 15, 'bold'), bd=3,
relief=RIDGE,
cursor='hand2', bg='red', fg='white', activeforeground='white', activebackground='red')
btn_1.place(x=100, y=350, width=220, height=35)
def first_window(self):
self.new_window = Toplevel(self.root)
self.app = first(self.new_window)
if __name__ == '__main__':
main()
I understand this question is quite common but I cant find a soloution on here which would be applicable for my code.
You can destroy the previous window and start a new window using Tk class
Here is an example
from tkinter import *
from tkinter.ttk import Button
root = Tk()
root.title("title")
root.geometry("800x500")
def window2():
root.destroy()
window2_main = Tk()
Label(window2_main, text="Bye Bye").pack()
window2_main.mainloop()
a = Button(text="Click This", command=window2)
a.pack()
root.mainloop()

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()

Retriving output from two entry dialog box with python

I have the following code to generate a two entry input dialog box and a button to close the "app".
However I cannot cannot get the values out of the outputs. They always come out as x and N. The code was not developed by me since I am a beginner with python. Can anyone give me hand with this?
from tkinter import Tk, Text, TOP, BOTH, X, N, LEFT, RIGH
from tkinter.ttk import Frame, Label, Entry, Button
class SimpleDialog(Frame):
def __init__(self):
super().__init__()
self.output1 = ""
self.output2 = ""
self.initUI()
def initUI(self):
self.master.title("Simple Dialog")
self.pack(fill=BOTH, expand=True)
frame1 = Frame(self)
frame1.pack()
lbl1 = Label(frame1, text="Input1", width=6)
lbl1.pack(side=LEFT, padx=5, pady=10)
self.entry1 = Entry(frame1)
self.entry1.pack(padx=5, expand=True)
frame2 = Frame(self)
frame2.pack()
lbl2 = Label(frame2, text="Input2", width=6)
lbl2.pack(side=LEFT, padx=5, pady=10)
self.entry2 = Entry(frame2)
self.entry2.pack(padx=5, expand=True)
frame3 = Frame(self)
frame3.pack()
btn = Button(frame3, text="Submit", command=self.onSubmit)
btn.pack(padx=5, pady=10)
def onSubmit(self):
self.output1 = self.entry1.get()
self.output2 = self.entry2.get()
self.quit()
def main():
# This part triggers the dialog
root = Tk()
root.geometry("250x150+300+300")
app = SimpleDialog()
root.mainloop()
user_input = (app.output1, app.output2)
try:
root.destroy()
except:
pass
return user_input
if __name__ == '__main__':
main()
kind regards!

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()

Categories

Resources