How to create a tkinter toggle button?
Solution 1
The background and fg are set only in the if-clause. You need to set them also in the else
clause:
def onNightMode(self):
if index:
self.text.config(font=('courier', 12, 'normal'), background='black', fg='green')
else:
self.text.config(font=('courier', 12, 'normal'))
index = not index
i.e.,
else:
self.text.config(font=('courier', 12, 'normal'), background='green', fg='black')
Solution 2
You can import tkinter library (Use capital letter for python 2.7):
import Tkinter
Create tkinter objects...
root = tk.Tk()
...and tkinter button
toggle_btn = tk.Button(text="Toggle", width=12, relief="raised")
toggle_btn.pack(pady=5)
root.mainloop()
Now create a new command button called "toggle" in order to create the effect of "toggle" when you press playing on the relief property (sunken or raised) :
def toggle():
if toggle_btn.config('relief')[-1] == 'sunken':
toggle_btn.config(relief="raised")
else:
toggle_btn.config(relief="sunken")
At the end apply this behaviour on your button:
toggle_btn = tk.Button(text="Toggle", width=12, relief="raised", command=toggle)
Solution 3
Here's a code snippet that will help you with the toggle button animation if you would like to. You only need to add the functions that you want to execute when clicking of course, that's up to you.
'''
import tkinter as tk
# --- functions ---
def move(steps=10, distance=0.1):
if steps > 0:
# get current position
relx = float(frame.place_info()['relx'])
# set new position
frame.place_configure(relx=relx+distance)
# repeate it after 10ms
root.after(10, move, steps-1, distance)
def toggle(event):
if button["text"] == "Yes":
move(25, 0.02) # 50*0.02 = 1
button["text"] = "No"
print("Clicked on yes")
elif button["text"] == "No":
move(25, -0.02)
button["text"] = "Yes"
print("Clicked on no")
# --- main --
root = tk.Tk()
frame = tk.Frame(root, background='red')
frame.place(relx=0, rely=0, relwidth=0.5, relheight=1)
# to center label and button
#frame.grid_columnconfigure(0, weight=1)
#frame.grid_rowconfigure(0, weight=1)
#frame.grid_rowconfigure(3, weight=1)
button = tk.Button(frame, text='Yes',width=5,height=1)
button.place(relx=0.25,rely=0.5,relwidth=0.5, relheight=0.1)
button.bind("<Button-1>",toggle)
root.mainloop()
Potato_head
Updated on April 14, 2020Comments
-
Potato_head about 4 years
I've been working on a text editor using Tkinter in Python 2.7. A feature that I'm trying to implement is the Night Mode, where the user can toggle between a black background and a light one, that switches from light to dark with a click of the toggle button.
from Tkinter import * from tkSimpleDialog import askstring from tkFileDialog import asksaveasfilename from tkFileDialog import askopenfilename from tkMessageBox import askokcancel Window = Tk() Window.title("TekstEDIT") index = 0 class Editor(ScrolledText): Button(frm, text='Night-Mode', command=self.onNightMode).pack(side=LEFT) def onNightMode(self): if index: self.text.config(font=('courier', 12, 'normal'), background='black', fg='green') else: self.text.config(font=('courier', 12, 'normal')) index = not index
However, on running the code, it is always in the night mode and the toggle doesn't work. Help. Source Code: http://ideone.com/IVJuxX
-
unutbu about 10 yearsThe
UnboundLocalError
is due to the assignment toindex
which makes it a local variable by default when you really want it to refer to the global variable. The quick fix is to add the statementglobal index
inside the function. But a better fix would be to avoid using a mutable global and instead makeindex
an instance attribute,self.index
. -
Russell Smith over 9 yearsYour code isn't formatted properly. Also, code-only answers aren't usually as good with code plus an explanation. Can you explain a bit why your code solves the problem?
-
Albe over 9 yearsI do not know English well but I know very well python: What do you mean formatted propely? For Python 2.7 works fine !!!! Copy it and paste into a text file and save it as .py! Test before giving a bad comments!!!
-
Russell Smith over 9 yearsAt the time I wrote the comment, the body of
toggle
was indented the same as thedef
statement and you could not copy and paste it. Look at the history of the edits and you'll see your original version was edited by someone else to fix the indentation. -
Albe over 9 yearswas the first time and I was wrong with the editor of stack overflow for the code but I assure you that I was in good faith and that the code has always worked. Next time send me a private message and correct it instead of a negative comment and judgment !!!
-
Russell Smith over 9 yearsIt wasn't a negative comment, I was merely stating a fact. I didn't want to edit the answer because I thought you might not know how to format it properly (since it was originally wrong), and by making you fix it you would learn how to format your answers. I'm sorry if you were offended. My only intention was to help you write a better answer.
-
Albe over 9 yearsSorry but the tone of your response seemed very aggressive. Anyway thanks for the help, I think I learned to write properly with this editor; I rewrote a new answer with code comments.
-
Russell Smith over 9 yearsIt would have been better if you edited this answer, than to provide another answer with the same information.