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() ```
im beginner on python and as a practice i want to solve this ( https://www.practicepython.org/exercise/2014/07/05/18-cows-and-bulls.html ) by tkinter
when i run this code and press start button it hangs and no error is shown in pycharm, even when i debug
obviously the bug is in game code
can you help me with this?
from tkinter import *
import random
def entry_box():
global user_guess
start_button.destroy()
user_guess=Entry(win,font='Bradly 12', width=25)
user_guess.insert(END,'0000')
user_guess.place(x=150,y=150)
game()
def game():
global user_guess , result
digit=[]
num =[]
counter = 0
for i in range(4):
digit.append(random.randint(0,9))
while num != digit:
num = list(user_guess.get())
cow = 0
bull = 0
for i in range(4):
if int(num[i]) in digit:
if int(num[i])==digit[i]:
cow += 1
else:
bull += 1
counter += 1
result.set('cow = %d \n bull = %d'%(cow,bull))
result.set('WELL DONE! YOU FOUND IT AFTER %d GUESS ' %counter )
win = Tk()
win.title('Let\'s play')
frame = Frame(win, height=300, width=500, bg='lightblue')
frame.pack()
result = StringVar()
result.set('cow=0\nbull=0')
start_button = Button(win , text='start', font='Broadway 15',command = entry_box)
start_button.place(x=200, y=175)
results = Label(win, textvariable=result, font='Broadway 20',bg='lightblue', fg='darkblue')
results.place(x=200 , y=0)
win.mainloop()
Your code hangs because of multiple reasons:
as #furas mentioned, num != digit will always be False, because you compare list of chars with list of digits;
Even if you fix this, your code will just never exit the loop: you will compare the first list [0,0,0,0] with the random one (num) and unless they are equal, you will get False. Then the code takes the same two lists, and compares them infinitely, with always the same outcome. You can see this easily if you add a print statement in the while loop.
This is one possible solution:
import tkinter as tk
import random
class MainGame(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.main_frame = tk.Frame(self, height=300, width=500, bg='lightblue')
self.main_frame.pack()
self.result = tk.StringVar()
self.result.set("Cow=0\nBull=0")
self.start_button = tk.Button(self.main_frame, text='start', font='Broadway 15', command=self.entry_box)
self.start_button.place(x=200, y=175)
self.results = tk.Label(self.main_frame, textvariable=self.result, font='Broadway 20', bg='lightblue',
fg='darkblue')
self.results.place(x=200, y=0)
def entry_box(self):
self.start_button.destroy()
self.user_guess = tk.Entry(self.main_frame, font='Bradly 12', width=25)
self.user_guess.insert(tk.END, '0000')
self.user_guess.place(x=150, y=150)
self.start_game()
def start_game(self):
user_input = self.user_guess.get()
num = [int(cypher) for cypher in user_input]
counter = 0
game_playing = True
while game_playing is True:
digit = [random.randint(0, 9) for i in range(4)]
cow, bull = 0, 0
for i in range(4):
if num[i] in digit:
if num[i] == digit[i]:
cow += 1
else:
bull += 1
counter += 1
print("Turn {}: cows = {}\t bulls={}".format(counter, cow, bull))
if cow == 4:
print("digit = {}\t num = {}".format(digit, num))
game_playing = False
if __name__ == "__main__":
game = MainGame()
game.mainloop()
First thing: do not use global imports (from tkinter import *). Instead use import tkinter as tk.
Then let's look at your entry_box: the function as you defined it takes no argument, but then you expect it to delete the start_button: the only reason this works is because the function is defined in the same script, but as soon as you move it to another script for example, it will fail. You did the same with result, which is defined in the main body, but then used in game, and for the win variable used to set the user_guess Entry widget.
The solution for this is to 1) reformat your code to account for these changes, which can work for something this small 2) use global variables, but this is usually considered a bad practice, because as your code grows it becomes a pain to track them down (plus many other reasons) 3) use classes, which is what I did here.
So here is what I did: I create a class, and in the __init__ I put the things I want to have available when the script starts, or that I generally want to use throughout the game: the main frame where I will place the widgets, the results or the start button.
Then the entry_box function: You see that I pass just self: since the start button was defined as self.start_button in the __init__, there is no reason to pass it as an argument, because it is already stored in self as an attribute. Same with the main_frame where I put the Entry widget.
Lastly the game function: here, I make sure that the comparison between num and digit is between int numbers. Then if the comparison fails, I draw another random list of 4 elements for digit and repeat. The results are printed in the terminal.
This is by no means perfect, and you can easily improve it in a few ways:
1) the comparison between the lists can be easily made faster and shorter with numpy;
2) I did not update the results widget. You should be able to do it with what I told you here.
3) I assume you want the user to input the user_guess. You just have to modify a bit this code
Hope it helps!
In my program, the entry widget no longer validates after the delete command has been used on it - the idea is that if it meets a certain requirement, the text in the box is automatically deleted but continues to validate the input.
from tkinter import *
TEXT_TO_MATCH = 'APPLE'
def validate(userinput):
if userinput == TEXT_TO_MATCH:
print(True)
input_box.delete(0, END)
else:
print(False)
return True
window = Tk()
window.title('Delete after validation')
reg = window.register(validate)
input_box = Entry(window, validatecommand=(reg, '%P'), validate='all')
input_box.pack()
window.mainloop()
The entry widget automatically resets the validate option to "none" when you edit the entry widget from within the validation function.
You can re-enable the validation by using after_idle to reset the validate option after control has been returned to mainloop
def validate(userinput):
if userinput == TEXT_TO_MATCH:
input_box.delete(0, END)
input_box.after_idle(lambda: input_box.configure(validate="all"))
return True
So I have a currency which is increasing (that system is working fine). The first part updates the label every 100 ms. I have another button which triggers the second function which is supposed to clear the labels from the first. It sets home_status equal to 0 which should in theory run Money.place_forget() to clear the code. I have tested each part individually and it works but when I put the clears inside the elif statement it doesn't. It does not give me any errors, it just simply doesn't do anything (it does print END OF UPDATE HOME so the elif is triggered).
Any suggestions?
def updatehome(self):
print("UPDATE HOME")
global buy_button, home_status, currency
MoneyLabel = Label(self, text = "Money: ")
MoneyLabel.place(x = 5, y = 70)
Money = Label(self, text=currency)
Money.place(x = 50, y = 70)
if (home_status == 1):
self.after(100, self.updatehome)
elif (home_status == 0):
print("END OF UPDATE HOME")
Money.place_forget()
MoneyLabel.place_forget()
def clearhome(self):
print("CLEAR HOME")
global home_status
home_status = 0
you are creating ten labels every second, all stacked on top of each other, but you are only deleting the very last label you create.
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()