it is my first time using tkinter. I have an entry box on the first window, and I created radio buttons on different windows. The problem is that they are already selected before I click any of them. How can I change all buttons to be deselected?
I am not sure if my codes are right or not.
from tkinter import *
from tkinter import messagebox
class SortingHat:
# Constructor
def __init__(self):
# Create main window
self.__main_window = Tk()
self.__main_window.geometry('300x200')
self.__main_window.title('Sorting Hat')
bg_image = PhotoImage(file = "HarryPotterlogo1.png")
bg_label = Label(self.__main_window, image = bg_image, bd=0)
bg_label.grid(row=1, column=0)
bg_label.image = bg_image
self.__first_label = Label(self.__main_window, text = \
'Enter Your Name.', fg = 'gold', bg = 'brown4')
self.__first_label.grid(row=2, column=0)
# Create Entry box
self.__entry = Entry(self.__main_window)
self.__entry.bind('<Return>', self.entry_action)
self.__entry.grid(row=3, column=0)
self.__button = Button(self.__main_window, text = 'Enter', \
fg = 'white', bg = 'black', command = self.action)
self.__button.grid(row=3, column=0, sticky = 'E')
self.__next_button = Button(text = 'Next', height = 1, width = 10, \
fg = 'black', bg = 'white', command = self.next1)
self.__next_button.grid(row=4, column=0, sticky ='W')
# Create OK button and Quit button
self.__quit_button = Button(text='Quit', height = 1, width = 10, \
command=self.__main_window.destroy)
self.__quit_button.grid(row=4, column=0, sticky = 'E')
def next1(self):
self.__new_window1 = Tk()
self.__new_window1.configure(bg = 'brown4')
self.__new_window1.title('Question 1')
self.__second_label = Label(self.__new_window1, text = \
'What is your favorite color? (10 points)', \
fg = 'gold', bg = 'brown4')
self.__second_label.grid(row=0, column=0, sticky = 'W')
# Question Radiobutton
self.__rb_var1 = IntVar()
# Create First question Radiobutton widgets
self.__rb1 = Radiobutton(self.__new_window1, text='a. Red and Gold', fg ='red', \
bg = 'brown4', variable=self.__rb_var1, value = 1)
self.__rb2 = Radiobutton(self.__new_window1, text='b. Green and Silver', fg = 'green', \
bg = 'brown4', variable=self.__rb_var1 , value = 2)
self.__rb3 = Radiobutton(self.__new_window1, text='c. Yellow and Black', fg = 'gold', \
bg = 'brown4', variable=self.__rb_var1, value = 3)
self.__rb4 = Radiobutton(self.__new_window1, text='d. Blue and Bronze', fg = 'blue', \
bg = 'brown4', variable=self.__rb_var1, value = 4)
self.__rb1.grid(row=1, column=0)
self.__rb2.grid(row=2, column=0)
self.__rb3.grid(row=3, column=0)
self.__rb4.grid(row=4, column=0)
I want all buttons to be deselected when the program starts.
The problem is that you shouldn't be opening a new Tk() window, instead you should be creating a new Toplevel() window, that will fix the issue.
So instead of self.__new_window1 = Tk() use self.__new_window1 = Toplevel()
Try this.
def next1(self):
self.__new_window1 = Toplevel()
self.__new_window1.configure(bg = 'brown4')
self.__new_window1.title('Question 1')
# Question Radiobutton
self.__rb_var1 = IntVar()
# Create First question Radiobutton widgets
self.__rb1 = Radiobutton(self.__new_window1, text='a. Red and Gold', fg ='red', bg = 'brown4', variable=self.__rb_var1, value = 1)
self.__rb2 = Radiobutton(self.__new_window1, text='b. Green and Silver', fg='green', bg='brown4', variable=self.__rb_var1, value=2)
self.__rb3 = Radiobutton(self.__new_window1, text='c. Yellow and Black', fg='gold', bg='brown4', variable=self.__rb_var1, value=3)
self.__rb4 = Radiobutton(self.__new_window1, text='d. Blue and Bronze', fg='blue', bg='brown4', variable=self.__rb_var1, value=4)
self.__rb1.grid(row=1, column=0)
self.__rb2.grid(row=2, column=0)
self.__rb3.grid(row=3, column=0)
self.__rb4.grid(row=4, column=0)
Try
self.__rb1.deselect()
self.__rb2.deselect()
self.__rb3.deselect()
self.__rb4.deselect()
Related
I have created a tkinter GUI using a for loop. it has some labels, entry boxes and 2 buttons. One buttons pull whatever has been entered in the entry boxes and second button populate the entry boxes based on a list. First button is working fine, but second button (FETCH button) gives this error "Entry' object has no attribute 'set'" . Can someone help and confirm what am I doing wrong?
below is the code
from tkinter import *
bg_color_2 = "#d9ffff"
background_color = bg_color_2
button_color = "#ffe08a"
white_font_color = "##ffffff"
black_font_color = "000000"
relief_type = "ridge"
width_of_window = 938
height_of_window = 833
root = Tk()
root.configure(bg= background_color)
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x_coordinate = (screen_width/2) - (width_of_window/2)
y_coordinate = (screen_height/2) - (height_of_window/2)
root.geometry("%dx%d+%d+%d" % (width_of_window, height_of_window, x_coordinate, y_coordinate))
def send():
rule_entry = []
for entries in my_entries:
rule_entry.append(entries.get())
def fetch():
rule_label_list = ['test1', 'test2', 'test3', 'test4', 'test5', 'test5', 'test6', 'test7', 'test8', 'test9', 'test10', 'test11', 'test12', 'test13', 'test14', 'test15', 'test16', 'test17', 'test18']
i = 0
print(my_entries)
for a in my_entries:
a.set(rule_label_list[i])
i + i + 1
root.title("Result Rule")
root.minsize(width_of_window, height_of_window)
root.maxsize(width_of_window, height_of_window)
rule_label_list = ['label1', 'label2', 'label3', 'label4', 'label5', 'label5', 'label6', 'label7', 'label8', 'label9', 'label10', 'label11', 'label12', 'label13', 'label14', 'label15', 'label16', 'label17', 'label18']
my_entries = []
for a in range(0,19):
my_label = Label(root, text=rule_label_list[a], fg= 'black', bg= bg_color_2, justify = LEFT, width=15,font=("bold", 10), anchor=W, borderwidth = 2)
my_label.grid(row=a, column=0, pady=5, padx=5)
my_entry_box = Entry(root, fg= 'black', bg='#FFFFFF', justify = LEFT, width=65,font=("bold", 10))
my_entry_box.grid(row=a, column=1, columnspan = 4, pady=5)
my_entries.append(my_entry_box)
Button(root, text='SEND', bg='#ffc200',fg='black', font=("bold", 10), width=15, height = 1,command = send).grid(row=20,column=0,pady=5, padx=5)
Button(root, text='FETCH', bg='#ffc200',fg='black', font=("bold", 10), width=15, height = 1,command = fetch).grid(row=20,column=1,pady=5, padx=5)
root.mainloop()
a = DoubleVar()
a.set(rule_label_list[i])
Try to add DoubleVar in line 34.
It helped me
This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 1 year ago.
The goal of this project is to have a user be able to enter a m and b value into a tkinter window and have a graph show up when a button is pressed. There is multiple windows. There is a click to start button, and a menu to select the type of graph. Currently I am just focusing on getting the linear graph working. When the linear window is reached it prompts the user to enter a m and b value (through entries).
When the graph button is pressed I have coded for it to print the m and b value out. As of right now I cannot get it to print out in the console. If anyone could help up let me know thanks!
Code:
from tkinter import *
root = Tk()
root.geometry("500x500")
class testInputs():
def __init__(self,m,b):
#self.displaygframe = Frame(root)
#self.displayglabe = Label(self.displaygframe,
#text="Test for now",
#font= "ComicSansMS 14")
print(m)
print(b)
class selectGraph(): #2
def __init__(self):
self.gselectframe = Frame(root)
self.gselectlabel = Label(self.gselectframe,
text = "Select Graph Type",
font= "ComicSansMS 14")
self.Var = IntVar()
#define buttons
self.linearButton = Radiobutton(self.gselectframe,
text="Linear",
variable = self.Var,
value=1)
self.quadraticButton = Radiobutton(self.gselectframe,text="Quadratic",
variable = self.Var,
value = 2)
self.confirmButton = Button(self.gselectframe, text = "Continue", command = self.transferAnswer,
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
self.sgBack = Button(self.gselectframe, text = "Back", command = self.backButton,
fg = "red", font = "ComicSansMS 5",
bd = 2, bg = "light green")
#pack
self.gselectlabel.pack()
self.linearButton.pack(anchor=W)
self.quadraticButton.pack(anchor=W)
self.confirmButton.pack()
self.gselectframe.pack()
mainloop()
def transferAnswer(self):
answer= self.Var.get()
print(str(answer))
self.gselectframe.destroy()
getEquation(answer)
def backButton(self):
self.gselectframe.destroy()
introWindow()
class getEquation(): #3
def __init__(self, answer):
if answer == 1:
self.linearInput()
if answer == 2:
self.quadraticInput()
else:
selectGraph()
def linearInput(self):
self.linearFrame = Frame(root)
#define widgets
self.linearLabel = Label(self.linearFrame,
text = "Enter Linear Equation",
font= "ComicSansMS 14")
self.linearBack = Button(self.linearFrame, text = "Back", command = self.backButtonLinear,
fg = "red", font = "ComicSansMS 5",
bd = 2, bg = "light green")
formatLabel = Label(self.linearFrame,
text="Format:",
font="ComicSansMS 14")
equationLabel = Label(self.linearFrame,
text="y=mx+b",
font="ComicSansMS 14",
fg="midnight blue")
#name = StringVar()
#name2 = StringVar()
self.mLabel = Label(self.linearFrame,
text= "m=",
font= "ComicSansMS 14")
self.mInput = Entry(self.linearFrame,
width =2, font="ComicSansMS 14")
self.bLabel = Label(self.linearFrame,
text = "b=",
font = "ComicSansMs 14")
self.bInput = Entry(self.linearFrame,
width=2,
font="ComicSansMS 14")
#get info from widget
m = self.mInput.get()
b = self.mInput.get()
self.graphButton = Button(self.linearFrame, text = "Graph", command = self.nextFromLinear(m,b), #error from here
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
#place widgets on screen
#self.linearFrame.pack()
self.linearLabel.grid(row=0,column=0)
formatLabel.grid(row=1,column=0)
equationLabel.grid(row=2, column=0)
self.bInput.grid(row=4, column=1)
self.bLabel.grid(row=4, column=0)
self.mInput.grid(row=3, column=1)
self.mLabel.grid(row=3,column= 0)
self.graphButton.grid(row=5, column=1) #error from here
self.linearBack.grid(row=5,column=0)
self.linearFrame.pack()
mainloop()
def quadraticInput(self):
self.quadraticFrame = Frame(root)
self.quadraticLabel = Label(self.quadraticFrame,
text = "Enter Quadratic Equation",
font= "ComicSansMS 14")
self.quadraticLabel.pack()
self.quadraticBack = Button(self.quadraticFrame, text = "Back", command = self.backButtonQuadratic,
fg = "red", font = "ComicSansMS 5",
bd = 2, bg = "light green")
self.quadraticBack.pack(anchor=SW)
self.quadraticFrame.pack()
mainloop()
def backButtonLinear(self):
self.linearFrame.destroy()
selectGraph()
def backButtonQuadratic(self):
self.quadraticFrame.destroy()
selectGraph()
def nextFromLinear(self,m,b):
#self.linearFrame.destroy()
#testInputs(m,b)
print(m)
print(b)
#Figuring out how to write singular back button function for all equation Frames:
#def backButton(self, frame1):
#frame1.destroy()
#selectGraph
class introWindow(): #1
def __init__(self):
self.introframe = Frame(root)
self.introlabel = Label(self.introframe,
text = "Graphing Program",font="ComicSansMS 14")
self.introbutton = Button(self.introframe, text = "Click to start", command = self.windowRemoval,
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
self.introlabel.pack()
self.introbutton.pack()
self.introframe.pack()
mainloop()
def windowRemoval(self):
self.introframe.destroy()
selectGraph()
introWindow()
The command argument to Button() must be a function reference, not a call to the function. You're calling the function when you create the button, not when it's clicked.
Use a lambda to create an anonymous function. And it has to call get() when it's called, you can't call it when creating the button, or you'll get the initial values of the inputs, not what the user has entered into them.
self.graphButton = Button(self.linearFrame, text = "Graph",
command = lambda: self.nextFromLinear(self.mInput.get(),self.bInput.get()), #error from here
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
root = Tk()
root.title('Tic-Tac-Toe by Ahmed')
root.geometry('500x500')
logo = PhotoImage(file = 'download.gif')
style = ttk.Style()
style.theme_use('clam')
print(style.theme_names())
style.configure('TButton', background = 'black', foreground = 'white', font = ('Arial', 30, 'bold'))
ttk.Label(root, text = 'Welcome to Tic-Tac-Toe by Ahmed', background = 'black', foreground = 'red', font = ('Arial',20,'italic'), anchor = 'center')\
.grid(row = 0, column = 1, sticky = 'ew')
playbtn = ttk.Button(root, text = 'Play')
playbtn.grid(row = 1, column = 1, sticky = 'snew')
root.call('wm','iconphoto',root,logo)
root.columnconfigure(1, weight = 1)
root.rowconfigure(1, weight = 2)
root.mainloop()
i've tried this code but the button color automatically change when i put the cursor on it, i've also tried to use (activebackground) but it still the same :/ , how to solve that ?
style.map("TButton", foreground=[('!active', 'white'), ('active', 'white')], background=[('!active', 'red'), ('active', 'red')], font = [('!active', ('Arial', 30, 'bold')), ('active', ('Arial', 30, 'bold'))])
it's ok, this code solved the problem ! :)
So I have multiple buttons
and i need the buttons of each name:
i.e. Violet button to turn the LABEL above it into violet,
and purple button to turn the above LABEL purple.
AND the reset button resets them all to grey.
AND if someone could fix my code so that the spacing of the "RESET" button is between purple and Blue (but still a row down), that'd be greatly appreciated.
WHAT MY CODE DOES NOW:
It turns all of the boxes all the colours.
How do I make it so when I press the one button, the one label changes colour AND I wish to do this in one function if possible (i've already thought of making multiple functions and thought this would be nicer).
Import the Tkinter functions
from tkinter import *
# Create a window
the_window = Tk()
# Give the window a title
the_window.title('MULTI Button Colour')
#Variables
window_font = ('Arial', 8)
button_size = 10
label_size = 7
margin_size_width = 10
margin_size_height = 2
label_violet = Label(the_window, padx = margin_size_width, pady = margin_size_height, bg = 'grey', width = label_size)
label_violet.grid(row = 0, column = 0)
label_purple = Label(the_window, padx = margin_size_width, pady = margin_size_height, bg = 'grey', width = label_size)
label_purple.grid(row = 0, column = 1)
label_blue = Label(the_window, padx = margin_size_width, pady = margin_size_height, bg = 'grey', width = label_size)
label_blue.grid(row = 0, column = 2)
label_green = Label(the_window, padx = margin_size_width, pady = margin_size_height, bg = 'grey', width = label_size)
label_green.grid(row = 0, column = 3)
def change_colour():
if violet_button:
label_violet['bg'] = 'violet'
if purple_button:
label_purple['bg'] = 'purple'
if blue_button:
label_blue['bg'] = 'blue'
if green_button:
label_green['bg'] = 'green'
# if reset_button:
# label_violet['bg'] = 'grey'
# label_purple['bg'] = 'grey'
# label_blue['bg'] = 'grey'
# label_green['bg'] = 'grey'
violet_button = Button(the_window, text = 'Violet', width = button_size,
font = window_font, command = change_colour)
purple_button = Button(the_window, text = 'Purple', width = button_size,
font = window_font, command = change_colour)
blue_button = Button(the_window, text = 'Blue', width = button_size,
font = window_font, command = change_colour)
green_button = Button(the_window, text = 'Green', width = button_size,
font = window_font, command = change_colour)
reset_button = Button(the_window, text = 'RESET', width = button_size,
font = window_font, command = change_colour)
#----------------------------------------------------------------
violet_button.grid(row = 1, column = 0, padx = margin_size_width, pady = margin_size_height)
purple_button.grid(row = 1, column = 1, padx = margin_size_width, pady = margin_size_height)
blue_button.grid(row = 1, column = 2, padx = margin_size_width, pady = margin_size_height)
green_button.grid(row = 1, column = 3, padx = margin_size_width, pady = margin_size_height)
reset_button.grid(row = 2, column = 1, pady = margin_size_height)
# Start the event loop to react to user inputs
the_window.mainloop()
This should do what you want:
def get_function(cmd):
def change_colour():
if 'violet' == cmd:
label_violet['bg'] = 'violet'
if 'purple' == cmd:
label_purple['bg'] = 'purple'
if 'blue' == cmd:
label_blue['bg'] = 'blue'
if 'green' == cmd:
label_green['bg'] = 'green'
if 'reset' == cmd:
label_violet['bg'] = 'grey'
label_purple['bg'] = 'grey'
label_blue['bg'] = 'grey'
label_green['bg'] = 'grey'
return change_colour
violet_button = Button(the_window, text = 'Violet', width = button_size,
font = window_font, command = get_function('violet'))
purple_button = Button(the_window, text = 'Purple', width = button_size,
font = window_font, command = get_function('purple'))
blue_button = Button(the_window, text = 'Blue', width = button_size,
font = window_font, command = get_function('blue'))
green_button = Button(the_window, text = 'Green', width = button_size,
font = window_font, command = get_function('green'))
reset_button = Button(the_window, text = 'RESET', width = button_size,
font = window_font, command = get_function('reset'))
For the issue with the reset button, just specifie the columnspan argument of the grid function:
reset_button.grid(row = 2, column = 1, pady = margin_size_height, columnspan = 2)
You have a lot of code in there that you copy / paste. Computers are really good at repeating things with a few variables changed. You could argue that that's ALL a computer is good at. So by doing that yourself, you are doing the computer's job. Also, you are making more work for your future self if you want to change something later. It's much better to put things in a single location, so that you can make a single change later instead of changing for every label. I can see you thought about this a little already since you have so many constants. Taking that one step further is to make a "constant" widget that all your instances copy from. It's a little advanced, but here's how you would do that:
import tkinter as tk
# Constants (aka variables that don't change during the program run)
BUTTON_SIZE = 10
FONT=('Arial', 8)
class Corey(tk.Frame):
'''a new widget that combines a Label and a Button'''
instances = []
def __init__(self, master=None, color='grey', **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.color = color
self.lbl = tk.Label(self, bg=color) # set initial color
self.lbl.grid(sticky='nsew') # sticky makes the label as big as possible
btn = tk.Button(self, text=color.title(), width=BUTTON_SIZE, command=self.colorize, font=FONT)
btn.grid()
self.instances.append(self)
def colorize(self):
self.lbl.config(bg=self.color)
#classmethod
def reset(cls):
for widget in cls.instances:
widget.lbl.config(bg='grey')
# Create a window
the_window = tk.Tk()
# Give the window a title
the_window.title('MULTI Button Colour')
# make some Corey widgets
colors = 'violet', 'purple', 'blue', 'green'
for col, color in enumerate(colors):
widget = Corey(the_window, color)
widget.grid(row=0, column=col, padx=10, pady=2)
reset_button = tk.Button(the_window, text = 'RESET', width=BUTTON_SIZE, command=Corey.reset, font=FONT)
reset_button.grid(row=1, column=0, columnspan=len(colors), pady=4)
the_window.mainloop()
The immediate advantage is that in order to add or subtract colors from my version, you only have to change one line. Also, if you want to change the appearance, say add a relief or change the button to a checkbox, again you only have to change a single line. Subclasses like this are a huge part of GUI design, I recommend you jump into this as soon as you can.
I am coding a python script that can display the buttons that I select to a label.
this program is containing 4 radiobutton and 1 label.
so far the problem of my program is that my program can not be repeated. Also I need to have a border surround the label.
I am using python 2.7 and I cannot post image because I don't have enough reputation
= Label(the_window, text = 'Null', fg = 'black',font = ('Times', 36), width = 8)
button.grid(row=2,column=1)
button.grid(row=3,column=1)
button.grid(row=2,column=2)
button.grid(row=3,column=2)
this is my setup
https://repl.it/BJcH
You can add a border to your label by specifying a relief:
direction_status = Label(the_window, text = 'Null', fg = 'black',
font = ('Times', 36), width = 8, relief=GROOVE)
Rather than using four BooleanVars as value attributes for your radio buttons, use a single IntVar. This will indicate to Tkinter that the radio buttons belong in the same group, and will ensure that only one can be selected at a time.
from Tkinter import *
# Create a window
the_window = Tk()
# Give the window a title
the_window.title('Compass')
##Label widget to display initial Compass's status
direction_status = Label(the_window, text = 'Null', fg = 'black',
font = ('Times', 36), width = 8)
## Function that define the label's text when radiobuttion is being selected
def update_the_window():
if v.get() == 1:
direction_status['text'] = 'NW'
if v.get() == 2:
direction_status['text'] = 'SW'
if v.get() == 3:
direction_status['text'] = 'NE'
if v.get() == 4:
direction_status['text'] = 'SE'
## Label Frame for direction_status
direction_status_frame = LabelFrame(the_window, relief = 'groove',
borderwidth = 2)
v = IntVar()
## 4 Buttons that change the status sorted by directions
NW_button = Radiobutton(text = 'North-West', variable = v,
value= 1, command=update_the_window, padx=20)
NW_button.pack(anchor=W)
SW_button = Radiobutton(text = 'South-West', variable = v,
value= 2, command = update_the_window, padx=20)
SW_button.pack(anchor=W)
NE_button = Radiobutton(text= 'North-East', variable = v,
value= 3, command=update_the_window, padx=20)
NE_button.pack(anchor=W)
SE_button = Radiobutton(text= 'South-East', variable = v,
value= 4, command=update_the_window, padx=20)
SE_button.pack(anchor=W)
## Grid geometry to put 4 radio buttons into the GUI
NW_button.grid(row=2,column=1)
SW_button.grid(row=3,column=1)
NE_button.grid(row=2,column=2)
SE_button.grid(row=3,column=2)
## Grid geometry manager to put the widget into the root window
margin = 5 ##pixels
direction_status.grid(padx=margin, pady=margin, row=1, column=1, columnspan=2)
#--------------------------------------------------------------------#
# Start the event loop to react to user inputs
the_window.mainloop()
You could also use a StringVar instead, which cuts down on the size of update_the_window somewhat.
from Tkinter import *
# Create a window
the_window = Tk()
# Give the window a title
the_window.title('Compass')
# PUT YOUR CODE HERE-------------------------------------------------#
##Label widget to display initial Compass's status
direction_status = Label(the_window, text = 'Null', fg = 'black',
font = ('Times', 36), width = 8)
## Function that define the label's text when radiobuttion is being selected
def update_the_window():
direction_status['text'] = direction.get()
direction = StringVar()
direction.set("NW")
update_the_window()
## Label Frame for direction_status
direction_status_frame = LabelFrame(the_window, relief = 'groove',
borderwidth = 2)
## 4 Buttons that change the status sorted by directions
NW_button = Radiobutton(text = 'North-West', variable = direction,
value= "NW", command=update_the_window, padx=20)
NW_button.pack(anchor=W)
SW_button = Radiobutton(text = 'South-West', variable = direction,
value= "SW", command = update_the_window, padx=20)
SW_button.pack(anchor=W)
NE_button = Radiobutton(text= 'North-East', variable = direction,
value= "NE", command=update_the_window, padx=20)
NE_button.pack(anchor=W)
SE_button = Radiobutton(text= 'South-East', variable = direction,
value= "SE", command=update_the_window, padx=20)
SE_button.pack(anchor=W)
## Grid geometry to put 4 radio buttons into the GUI
NW_button.grid(row=2,column=1)
SW_button.grid(row=3,column=1)
NE_button.grid(row=2,column=2)
SE_button.grid(row=3,column=2)
## Grid geometry manager to put the widget into the root window
margin = 5 ##pixels
direction_status.grid(padx=margin, pady=margin, row=1, column=1, columnspan=2)
#--------------------------------------------------------------------#
# Start the event loop to react to user inputs
the_window.mainloop()