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__())
Related
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()
I am new to python and tkinter. I'm looking to make a simple window with a few buttons. When a button is pressed, I wish for it to disappear and instead reveal something behind it, a number, for instance.
How do I go about doing this? Below is an example code which generates a window with a button. Can I work with a code like this or should it look completely different?
from tkinter import *
class Button:
def __init__(self):
self.root = Tk()
self.root.title("Button program")
self.root.geometry("100x100")
self.frame = Frame(self.root)
self.btn = Button(self.root, width=2)
self.btn.grid(row=1, column=1)
self.root.mainloop()
Button()
How about this? You will have to rearrange it in the class 'cause I couldn't fit it in, but works for me
from tkinter import *
def press_btn():
btn.grid_forget()
lbl = Label(root, text="label", width=15)
lbl.grid(row=1, column=1)
root = Tk()
root.title("Button program")
root.geometry("100x100")
frame = Frame(root)
btn = Button(root, text="button", width=15, command=press_btn)
btn.grid(row=1, column=1)
root.mainloop()
I want to create two windows with one button in the first one one and one label in the second.
When i press the button the label in the second window should refresh and display the variable plus 1.
I dont want to close the second window and re open it afterwards.
Any ideas how that could be done?
import tkinter as tk
text = 1
root = tk.Tk()
root2 = tk.Tk()
label = tk.Label(root, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
def plus():
global text
text = text + 1
print(text)
button = tk.Button(root2, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
root2.mainloop()
This code should do the basics but the line to refresh the second window is still missing.
Hopefully anyone can tell me how to that :)
Use Toplevel() window instead of using Tk() as secondary windows. Tkinter is single threaded so using one mainloop() is sufficient for all the windows.
Now as you've asked that you want one button in one window and a label which updates in the second window, and also you can reopen the window without losing any progress if you close the second window.
Here is my way.
import tkinter as tk
text = 1
root = tk.Tk()
root2 = tk.Toplevel()
label = tk.Label(root2, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
def plus():
global text, root2, label
if not root2.winfo_exists(): # checks if the window is closed or not
root2 = tk.Toplevel()
label = tk.Label(root2, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
text += 1
label['text'] = text
button = tk.Button(root, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
Using IntVar() to update all the label values. Can use StringVar() for sting type:
Sample
import tkinter as tk
root = tk.Tk()
root2 = tk.Toplevel()
# This is a textvariable IntVar can also use StringVar for sting input
text = tk.IntVar()
text.set(1) # Set the initial to 1
# Use 'textvariable' instad of text
label = tk.Label(root2, bg="green", textvariable=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
label2 = tk.Label(root, textvariable=text)
label2.pack()
def plus():
global text, root2, label
if not root2.winfo_exists(): # checks if the window is closed or not
root2 = tk.Toplevel()
label = tk.Label(root2, bg="green", textvariable=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
text.set( text.get()+1 ) # incrementing by 1 ( text.get() will return the value )
button = tk.Button(root, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
I hope you may find something useful from my answer.
You can't run two mainloops in one thread. Your call to root.mainloop() blocks until you close the window. Once you close the window, it exits that method and runs root2.mainloop() because it's the next line of code.
One root pane can have multiple windows, you don't need to make a root2. You want to make two Toplevel windows
To expand upon the answer already given, you should use Toplevel rather than two root windows.
Also in order to change the text of the label you use label['text'] = str(text) to update the value.
import tkinter as tk
text = 1
root = tk.Tk()
root2 = tk.Toplevel()
def plus():
global text
text = text + 1
label['text'] = str(text)
label = tk.Label(root, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
button = tk.Button(root2, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
If I've understand, try this, every time you open a window, toplevel, the label in the new window is increment by 1
import tkinter as tk
class Test(tk.Toplevel):
def __init__(self, parent, count):
super().__init__()
self.parent = parent
self.count = tk.IntVar()
self.count.set(count)
self.title("I'm a new toplevel.")
self.init_ui()
def init_ui(self):
self.label = tk.Label(self, textvariable=self.count).pack()
self.close_me = tk.Button(self, text= "Close me", command = self.on_close_me).pack()
self.close_parent = tk.Button(self, text= "Close parent", command = self.on_close_parent).pack()
def on_close_me(self):
self.destroy()
def on_close_parent(self):
self.parent.on_close()
class App(tk.Frame):
def __init__(self,):
super().__init__()
self.master.title("Hello World")
self.count =0
self.init_ui()
def init_ui(self):
self.pack(fill=tk.BOTH, expand=1,)
f = tk.Frame()
w = tk.Frame()
tk.Button(w, text="Open", command=self.callback).pack()
tk.Button(w, text="Close", command=self.on_close).pack()
f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)
w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
def callback(self):
self.count +=1
obj = Test(self,self.count)
def on_close(self,evt=None):
self.master.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
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?
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!