Im in a need of a little help here, i feel like i have searched endlessly and been unable to corret my problem.
The case:
I have a checkbutton which have on value as 1 and off as 0, now i want to do an act if it is on and another if it is off.
My code goes:
#==Checkbox==#
check = IntVar()
checkbox = Checkbutton(labelframe, text="Tillad mere end én linje", variable = check, onvalue=1, offvalue=0)
checkbox.pack(side = RIGHT)
...
def go():
check.get()
print(check)
if(check == 0):
print("off")
w.delete(ALL)
tegnefladen()
update()
else:
print("on")
update()
You aren't actually setting the value. check is an object, and it won't ever be identical to 0. Basically, you want to compare check.get(). Try this:
def go():
print(check.get())
if(check.get() == 0):
print("off")
w.delete(ALL)
tegnefladen()
update()
else:
print("on")
update()
Related
I used this program for few weeks and it worked perfectly. Now, without changing anything, it doesn't work. More precisely, the orientation value doesn't change when you click on the radiobutton. Then, the program PosChoisie return 0 instead of either 1 or 2.
I'm on this program for 2 days, but even if I tried hard, I didn't found the error. Thanks for your futur help.
value=StringVar()
orientation = IntVar()
radiobutton_Horizontal = Radiobutton(fen, text="Horizontal", variable=orientation, value=1).pack()
radiobutton_Vertical = Radiobutton(fen, text="Vertical", variable=orientation, value=2).pack()
def PosChoisies():
L=[]
ori=IntVar()
ori = orientation.get()
if ori == 1:
o='horizontal'
L.append(o)
#print('horizontal')
elif ori == 2:
o='vertical'
L.append(o)
#print('vertical')
print(L)
print(ori)
return L
butValider = Button(fen, text="valider", relief = RAISED, command=lambda:(print(abs,ord,o)).pack()
fen.mainloop() ```
I have split the error handing into 3 parts, ( check_black, raise_error, delete_error)
About about the functions:
the check_blank() function checks if there are any errors in the input
entries and raise_error() function raises the error by gridding() a
ErrorLabel. and if the error have been resolved then delete_error()
function deletes the error label.
(there are 5 entry boxes and 4 check buttons, and a 'done' button)
( error should be raised if there's no input for all 5 Entries or at least one check button hasn't been checked )
this is the check_blanks() function:
def checkblanks(self):
flag = 0
if not self.Text1.get(): #text.get() and Answer1.get() etc stores input from entry so if there's no entry then it will be empty
flag = 1
if not self.Answer1.get():
flag = 1
if not self.Answer2.get():
flag = 1
if not self.Answer3.get():
flag = 1
if not self.Answer4.get():
flag = 1
if not self.var.get(): # var.get stores input from check button so if its not checked then there won't be anything stored in var.get()
flag += 2
if flag == 0: # flag = 0 means no error
self.ErrorLabel = None
self.add() #### EDIT ####
self.delete_error()
elif flag == 1 or flag == 2 or flag == 3: # if flag is 1 or 2 or 3 means there is error
self.raise_error(flag)
flag 0 = means no errors
flag 1 = means that there's no input in all 5 entries
flag 2 = means at least one check button hasn't been checked
flag 3 = means both above errors occurred
this is the raise error_function:
def raise_errors(self, flag):
if flag == 1 or flag == 3:
self.L5.grid_forget()
self.ErrorLabel = tk.Label(self.frame2, text="Error: Fill all the blanks !", fg='white', bg='red')
self.ErrorLabel.grid(row=7, column=0, pady=10)
elif flag == 2:
self.L5.grid_forget()
self.ErrorLabel = tk.Label(self.frame2, text="Error: check ✔️ the correct answer ", fg='white', bg='red')
self.ErrorLabel.grid(row=7, column=0, pady=10)
and the delete_error function:
def delete_error(self):
if self.ErrorLabel is not None: # checks if the error label exists
self.ErrorLabel.grid_forget()
but there is a problem:
When the error is raised and then error label is made; after the
errors are resolved then the error label is not deleted by
delete_error()
and sometimes multiple error labels overlap each other and it not very
efficient
I need to make the error handling functions more simple and work
properly.
EDIT:
also the function add() is called if flag == 0,( if there's no errors
) the add() function just creates a new frame
with the same entries and check buttons its and checks for errors all
over again.
its just a repeat loop
this is that function:
def add(self):
self.X += 1
self.frame2.grid_forget() # deleted main frame
self.amount_of_questions -= 1
self.question(self.X) # question() creates new frame with same widgets
It is over writing each label because you are creating new label for each function call and so on, so I think its safe for us now, to get rid of None and try to use config:
def checkblanks(self):
flag = 0
.....
self.ErrorLabel = tk.Label(self.frame2,fg='white',bg='red') # Define the variable with basic base options
if flag == 0:
self.delete_error()
elif flag == 1 or flag == 2 or flag == 3:
self.raise_error(flag)
and then delete_error() would be:
def delete_error(self):
self.ErrorLabel.grid_forget() # Now always errorlabel is defined, you might want to use winfo_exists
So now you have to use config to update the widget inside raise_errors():
def raise_errors(self, flag):
if flag == 1 or flag == 3:
self.L5.grid_forget()
self.ErrorLabel.config(text="Error: Fill all the blanks !") # Update the widget
self.ErrorLabel.grid(row=7, column=0, pady=10) # Grid it
elif flag == 2:
self.L5.grid_forget()
self.ErrorLabel.config(text="Error: check ✔️ the correct answer ") # Update the widget
self.ErrorLabel.grid(row=7, column=0, pady=10) # Grid it
Since I don't have a code to test this up with, this is based on imagination, I think you need winfo_exists inside delete_errors() too.
after the errors are resolved then the error label is not deleted by delete_error()
This might be due to the way self.ErrorLabel was defined as None. Now that it is always defined as a Label, it should be fine.
EDIT: Can you try moving the label inside of __init__:
def __init__(self):
....
self.ErrorLabel = tk.Label(self.frame2,fg='white',bg='red')
I tried writing a program that tests writing skills. (using tkinter)
For use type in y, press enter, write the sentence you were given press enter again and it outputs the time it took you. This is the part that works.
To add more flexibility I wanted to add a button that shuffles the sentence and gives you a new one. I've tried random.choice from a list, defining the variable as parameter and am currently stuck at random.randint. None of them have worked so far. They output a random sentence after launching the code, but the button simply does nothing.
heres the code of the function and further down where the button its used in. if the complete code is necessary to you please just ask for it :D
def change_sentence():
var = random.randint(0,5)
if var == 1:
sentence_var = "thats gonna work"
return sentence_var
if var == 2:
sentence_var = "probably"
return sentence_var
if var == 3:
sentence_var = "i guess"
return sentence_var
if var == 4:
sentence_var = "maybe?"
return sentence_var
if var == 5:
sentence_var = "please??"
return sentence_var
sentence_var = change_sentence()
shuffle_button = Button(root, text="Shuffle", command=change_sentence)
to conclude, i simply look for a way of making my button working.
Having your callback function return a variable doesn't really do anything. Specifically, it won't update the text in your GUI.
You should look into StringVar and using textvariable parameter for you text object. Here's a small example. I also cleaned up your if statement:
root = tk.Tk()
class tkApp:
def __init__(self, master):
self.sentence_var = tk.StringVar()
self.change_sentence()
sentence_text = tk.Label(master, textvariable=self.sentence_var)
shuffle_button = tk.Button(master, text="Shuffle", command=self.change_sentence)
sentence_text.pack()
shuffle_button.pack()
def change_sentence(self):
var = np.random.randint(1, 6)
if var == 1:
self.sentence_var.set("thats gonna work")
elif var == 2:
self.sentence_var.set("probably")
elif var == 3:
self.sentence_var.set("i guess")
elif var == 4:
self.sentence_var.set("maybe?")
elif var == 5:
self.sentence_var.set("please??")
myApp = tkApp(root)
root.mainloop()
You need to put a print statement inside the function if you just want to print the sentence. Your variable sentence_var will be assigned a string when calling the function but after that the Button will have no effect on it as it is not inside the function.
When I run this code:
currentquestion = 0
currentcheckbox = 1
which_radio_var = StringVar(inside_test_root)
while currentquestion < len(questions):
print('currentcheckbox', currentcheckbox)
Radiobutton(inside_test_root, text=questions[currentquestion], value=currentcheckbox, variable=which_radio_var, indicatoron=0, wraplength=30).grid(row=currentquestion+1, column=0)
currentquestion += 2
currentcheckbox += 1
x = which_radio_var.get()
I get the Radiobuttons coming up fine and everything works properly, apart from wen I try to test these radiobuttons with the code:
Button(inside_test_root, text='oof', command=print(x)).grid(column = 77, row = 77)
Nothing prints. Is it something to do with the nature i made the radiobuttons? I need a way to not know the amount of buttons that are being produced beforehand.
Any help would be much appreciated, thanks
Answer is as jasonharper said, I missed out the lambda, meaning that i was calling the print function the first time and never again
"command=print(x) means to print x right now, and use the return value of the print() function (which is None) as the command to execute when the button is clicked. command=lambda: print(which_radio_var.get()) would do the job. "
Updated code is now: (the variable 'x' has become 'radio' to fit with the rest of my program)
if questiontype == 'Multiple Choice':
currentquestion = 0
currentcheckbox = 1
which_radio_var = StringVar(inside_test_root)
print (which_radio_var)
while currentquestion < len(questions):
print('currentcheckbox', currentcheckbox)
Radiobutton(inside_test_root, text=questions[currentquestion], value=currentcheckbox, variable=which_radio_var, indicatoron=0, wraplength=30).grid(row=currentquestion+1, column=0)
currentquestion += 2
currentcheckbox += 1
print(which_radio_var.get())
radio = which_radio_var.get()
Button(inside_test_root, text='oof', command=lambda: print(radio)).grid(column = 77, row = 77)
from Tkinter import *
import random
def Factorer(a,b,c):
while True:
random_a1=random.randint(-10,10)
random_a2=random.randint(-10,10)
random_c1=random.randint(-10,10)
random_c2=random.randint(-10,10)
if random_a1==0 or random_a2 == 0 or random_c1 == 0 or random_c2 == 0:
pass
elif (random_a1*random_c2) + (random_a2*random_c1) == b and random_a1/random_c1 != random_a2/random_c2 and random_a1*random_a2==a and random_c1*random_c2==c:
break
print "y=(%dx+(%d))(%dx+(%d))" % (random_a1,random_c1,random_a2,random_c2)
root = Tk()
buttonSim1 = Button(root, text="Convert", command=lambda: Factorer(enterA.get(),enterB.get(),enterC.get()))
buttonSim1.grid(row=2, column=3)
enterA = Entry(root)
enterA.grid(row=1, column=1)
enterB = Entry(root)
enterB.grid(row=1, column=2)
enterC = Entry(root)
enterC.grid(row=1, column=3)
root.mainloop()
How can I get this code to run, every time I click the button It just crashes.
It works however if I remove the .get() and just insert numbers.
Thanks in advance
You are comparing strings to ints, you would need to cast a,b and c to int:
Tkinter.Button(root, text="Convert", command=lambda: Factorer(int(enterA.get()),int(enterB.get()),int(enterC.get())))
The root of the problem is that you're comparing strings to integers, so your infinite while loop never finishes. That is why the program hands and has to be force-quit.
The best solution is to have your button call a function that gets the data, formats it to the proper value, and then calls the function to do the work. Trying to squeeze all of that into a lambda makes for a program that is hard to debug.
For example:
def on_button_click():
a = int(enterA.get())
b = int(enterB.get())
c = int(enterC.get())
result = Factorer(a,b,c)
print(result)
Tkinter.Button(..., command=on_button_click)
By using a separate function, it gives you the opportunity to add print statements or pdb breakpoints so you can examine the data as it is running. It also makes it easier to add try/catch blocks to handle the case where the user didn't enter valid numbers.