win=Tk()
level1=matrixmaker(4)
def display(x,y):
if z["text"] == " ":
# switch to Goodbye
z["text"] = level1[x][y]
else:
# reset to Hi
z["text"] = " "
for x in range(0,4):
for y in range(0,4):
z=Button(win,text=" ", command=display(x,y))
z.grid(row=x,column=y)
I have this code but I don't know how to get the display function to work. How can I call the button and change the text without it having a hardcoded variable name?
You can't assign the command to the button with the called function (display(x, y)) because this assigned what this function returns (None) to the button's command. You need to assign the callable (display) instead.
To do this and pass arguments you'll need to use a lambda:
z = Button(win, text='')
z['command'] = lambda x=x, y=y, z=z: display(x, y, z)
z.grid(row=x, column=y)
Also, you'll want to change your display() function to accept another argument z so that the correct button gets changed (and correct the indentation):
def display(x,y,z):
if z["text"] == " ":
# switch to Goodbye
z["text"] = level1[x][y]
else:
# reset to Hi
z["text"] = " "
Related
I have a List which I go through and generate a Button for each element in the List. Now when I press the Button I would like to know what Text is inside the Button. Sadly I was not able to figure out how to do this.
Here is the entire Loop however the Last 3 rows are the important ones.
Listezumsortieren = [*self.root.ids.Kommentar.text]
x = 0
stelle = 0
for i in Listezumsortieren:
if x == 17:
Listezumsortieren.insert(stelle," \n")
x = 0
x = x+1
stelle = stelle + 1
if stelle > 65:
return
Zitatselbst = ''.join(Listezumsortieren)
btn = Button(text = '\n"' + Zitatselbst + '"' + "\n ~" + self.root.ids.field.text + "\n", size_hint = (0.8 , None))
btn.bind(on_press=lambda x:self.kek())
self.root.ids.Zitate.add_widget(btn)
Thanks for helping
To specify because of the first answer:
so for example if I have a list of [1,2,3] and have three buttons with the text: (1,2,3) no matter which button I click the Button will return "3" and not the actual text of the Button, Thanks for trying to help
This is because "Self" is not referring to the Button but rather to the class the Function is in (MainApp) so to be more precise I need to know how to get to the Button
The global isn't working properly and it says that
it does not know what text is, even though it is declared global.
def nguess():
answer = random.randint ( 1, 50 )
def check():
global attempts
attempts = 10
global text
attempts -= 1
guess = int(e.get())
if answer == guess:
text.set("yay you gat it right")
btnc.pack_forget()
elif attempts == 0:
text.set("you are out of attempts")
btnc.pack_forget ()
elif guess > answer:
text.set("incorrect! you have "+ str(attempts) + "attempts remaining. Go higher")
elif guess < answer:
text.set("incorrect! you have "+ str(attempts) + "attempts remaining. Go lower")
return
nw = tk.Toplevel(app)
nw.title("guess the number")
nw.geometry("500x150")
lable = Label(nw, text="guess the number between 1 - 50")
lable.pack()
e = Entry(nw, width = 40, borderwidth = 10)
e.pack()
btnc = Button(nw,text = "Check", command = check)
btnc.pack()
btnq = Button ( nw, text="Quit", command=nw.destroy )
btnq.pack()
text = StringVar()
text.set("you have ten attempts remaining ")
guess_attempts = Label (nw,textvariable = text)
guess_attempts.pack()
Well, what's going on is you're trying to get a variable before initialize it i.e. in check function you're calling a global text variable so what it means is you're bringing whatever text variable stores in global namespace, but the problem is text variable isn't exist in global namespace yet because you've created after calling the check function. Below I show an example:
def test():
global variable
print(variable)
test()
variable = 'Hello'
This will raise an error because of what I just explained, so what you have to do is something like this(based on the example):
def test():
global variable
print(variable)
variable = 'Hello'
test()
In short, initialize the text variable before calling the check function which uses global text
I'm trying to compare the input of an Entry box to the actual answer. This is one of my first python projects and I'm still very confused and to be honest I don't even know how to start asking the question.
The user will click either the addition or subtraction button. A string will appear asking "What does 4 + 5 equal?" The numbers are generated randomly.
I then insert an Entry box using the tkinter library. I don't know how to get() the input and compare it to the sum or difference of the actual numbers.
I was trying to follow this video but I've failed using other methods as well. FYI, I was focusing on the addition method mostly so if you test, that with addition first.
from tkinter import Entry
import tkinter as tk
import random as rand
root = tk.Tk()
root.geometry("450x450+500+300")
root.title("Let's play Math!")
welcomeLabel = tk.Label(text="LET'S PLAY MATH!").pack()
startLabel = tk.Label(text='Select a math operation to start').pack()
def addition():
a = rand.randrange(1,10,1)
b = rand.randrange(1,10,1)
global Answer
Answer = a + b
tk.Label(text="What does " + str(a) + " + " + str(b) + " equal? ").place(x=0, y=125)
global myAnswer
myAnswer = Entry().place(x=300, y= 125)
def checkAnswer():
entry = myAnswer.get()
while int(entry) != Answer:
if int(entry) != Answer:
tk.Label(text="Let's try again.").pack()
elif int(entry) == Answer:
tk.Label(text="Hooray!").pack()
addBtn = tk.Button(text="Addition", command=addition).place(x=100, y = 60)
subBtn = tk.Button(text="Subtraction", command=subtraction).place(x=200, y=60)
checkBtn = tk.Button(text="Check Answer", command=checkAnswer).place(x=300, y = 150)
tk.mainloop()
All you need to do to fix your issue is separate the creation of your Entry() object from the placing of it:
def addition():
a = rand.randrange(1,10,1)
b = rand.randrange(1,10,1)
global Answer
Answer = int(a + b)
tk.Label(text="What does " + str(a) + " + " + str(b) + " equal? ").place(x=0, y=125)
global myAnswer
myAnswer = Entry()
myAnswer.place(x=300, y= 125)
Entry() returns the entry object, which has a get() method. However, when you chain .place(), you return its result instead, which is None. Therefore you never actually store the Entry object in your variable.
Also, it is a good idea to ensure that Answer is an int as well.
to get the value of the answer do answer = myanswer.get() or any other variable name. To compare it to the correct answer do
if int(answer) == correctAnswer:
#the code
is that what you were asking?
Consider this and below is an example that responds to whether or not the number entered to answer is "Correct!" or "False!" when the user clicks on answer_btn:
import tkinter as tk
import random as rand
def is_correct():
global answer, check
if answer.get() == str(a + b):
check['text'] = "Correct!"
else:
check['text'] = "False!"
def restart():
global question, check
random_nums()
question['text'] = "{}+{}".format(a, b)
check['text'] = "Please answer the question!"
def random_nums():
global a, b
a = rand.randrange(1, 10, 1)
b = rand.randrange(1, 10, 1)
root = tk.Tk()
#create widgets
question = tk.Label(root)
answer = tk.Entry(root, width=3, justify='center')
check = tk.Label(root)
tk.Button(root, text="Check", command=is_correct).pack()
tk.Button(root, text="New question", command=restart).pack()
#layout widgets
question.pack()
answer.pack()
check.pack()
restart()
root.mainloop()
Here is my code:
# This program makes the robot calculate the average amount of light in a simulated room
from myro import *
init("simulator")
from random import*
def pressC():
""" Wait for "c" to be entered from the keyboard in the Python shell """
entry = " "
while(entry != "c"):
entry = raw_input("Press c to continue. ")
print("Thank you. ")
print
def randomPosition():
""" This gets the robot to drive to a random position """
result = randint(1, 2)
if(result == 1):
forward(random(), random())
if(result == 2):
backward(random(), random())
def scan():
""" This allows the robot to rotate and print the numbers that each light sensors obtains """
leftLightSeries = [0,0,0,0,0,0]
centerLightSeries = [0,0,0,0,0,0]
rightLightSeries = [0,0,0,0,0,0]
for index in range(1,6):
leftLight = getLight("left")
leftLightSeries[index] = leftLightSeries[index] + leftLight
centerLight = getLight("center")
centerLightSeries[index] = centerLightSeries[index] + centerLight
rightLight = getLight("right")
rightLightSeries[index] = rightLightSeries[index] + rightLight
turnRight(.5,2.739)
return leftLightSeries
return centerLightSeries
return rightLightSeries
def printResults():
""" This function prints the results of the dice roll simulation."""
print " Average Light Levels "
print " L C R "
print "========================="
for index in range(1, 6):
print str(index) + " " + str(leftLightSeries[index]) + " " + str(centerLightSeries[index]) + " " + str(rightLightSeries[index])
def main():
senses()
pressC()
randomPosition()
scan()
printResults()
main()
So, I am getting this error when I run my program.
NameError: global name 'leftLightSeries' is not defined
I understand that I must be doing something wrong related to the return statement. I'm not sure if I can only return one variable at the end of a user-defined function. If that were to be true, then I should probably separate the scan(): function. Anyways, I would appreciate any help on how to fix this error. Also, this is the result that I am looking for when I successfully complete my program:
Click Here
I am looking to complete the average values like the picture shows, but I am not worried about them at this point, only the list of values from the light sensors. I do not need to reach those exact numbers, the numbers will vary in the simulator.
If you want to return multiple items from scan(), don't use three separate return statements. Instead, do this:
return leftLightSeries, centerLightSeries, rightLightSeries
Also, when you call the function, you have to assign variable(s) to the returned values; it won't automatically create new local variables with the same names. So in main, call scan() like this:
leftLightSeries, centerLightSeries, rightLightSeries = scan()
I have made a coin flip button that shows the result in Label, every time the button is pressed, the result change according to the function.
def coin_flip(self):
sound_1 = SoundLoader.load('coin.wav')
res = random.randint(1,2)
if sound_1:
sound_1.play()
if res == 1:
self.coin_f_result.text = "HEAD"
else:
self.coin_f_result.text = "TAIL"
What I want to do is, showing the result in the Label, and then, after a second set the Label text as " ". Here's what I tried, but i only get the function calling delayed, and the label text is set directly to " ".
def coin_flip(self):
sound_1 = SoundLoader.load('dice.wav')
res = random.randint(1,2)
if sound_1:
sound_1.play()
if res == 1:
self.coin_f_result.text = "HEAD"
time.sleep(1)
self.coin_f_result.text = " "
else:
self.coin_f_result.text = "TAIL"
time.sleep(1)
self.coin_f_result.text = " "
Never use time.sleep() in an event driven framework such as kivy. It just blocks execution and as you saw, events are not handled. Use Clock.schedule_once() instead. For example, in the same class that has the coin_flip method, define
def reset_label(self, *args):
self.coin_f_result.text = ' '
And at the end of coin_flip() write
Clock.schedule_once(self.reset_label, 1)
For smooth transitions you can pair that with Animation, too.