I am new to Tkinter, and am trying to create a hangman app. I have already created a command-line version, so I thought it would be a nice beginning project. When learning I was told to use window.mainloop() for creating/updating, but my program contains a while loop, and so that hasn't worked. I am not able to type into the textbox i have created at all and when I click the button, it gives me a NameError saying textEntry in my click() method is not defined. Any help or guidance of where else to look would be much appreciated. Thanks! My code is posted below
from tkinter import *
from random import choice
def click():
guess = textEntry.get()
return guess
def main():
input_file = open('hangman_word_list.txt','r')
word_list = input_file.read().split()
window = Tk()
window.title("Play Hangman!")
window.configure(background="black")
p1 = PhotoImage(file='h1.gif')
p2 = PhotoImage(file='h2.gif')
p3 = PhotoImage(file='h3.gif')
p4 = PhotoImage(file='h4.gif')
p5 = PhotoImage(file='h5.gif')
p6 = PhotoImage(file='h6.gif')
Label(window,image=p1,bg="purple").grid(row=0,column=0,columnspan=4)
word = choice(word_list)
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
lives = 6
again = True
nowPhoto = p1
guess = 'empty'
while lettersLeft > 0 and again == True:
Label(window,text="Your word is "+hiddenWord ,bg="gray",fg="purple",font="none 12 bold").grid(row=1,column=0,sticky=W)
Label(window,text="Enter a letter: " ,bg="gray",fg="purple",font="none 12 bold").grid(row=2,column=0,sticky=W)
textEntry = Entry(window,width=5,bg="white")
textEntry.grid(row=2,column=1,sticky=W)
guess = Button(window,text="Guess",width=5,command=click).grid(row=3,column=2,sticky=W)
window.update()
main()
The mainloop() listens continously for any hook that you have defined, which means you don't have to worry about that. Just define the right hooks, like the button command.
I introduced a nicer way to handle the images by putting them in a list and then reducing the list for each image requested. This makes it easier to update the image.
Then put all processing, like checking if a uessed letter is in the word etc. in the click() function.
from tkinter import *
window = Tk()
# Make a list of all the pictures
pic_list = ['h6.gif','h5.gif','h4.gif','h3.gif','h2.gif','h1.gif']
img = PhotoImage(file=pic_list.pop()) # Get image from list of images
hangman = Label(window, image=img) # Save reference to the Label as
hangman.grid(row=0,column=0,columnspan=4) # you will update it later
# I simplified the word selection a bit
word = 'Wensleydale'
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
guess = 'empty'
# Build the rest of the GUI
Label(window,text="Your word is " + hiddenWord, bg="gray", fg="purple",
font="none 12 bold").grid(row=1, column=0, sticky=W, columnspan=4)
Label(window,text="Enter a letter: ", bg="gray", fg="purple",
font="none 12 bold").grid(row=2, column=0, sticky=W)
textEntry = Entry(window, width=10, bg="white")
textEntry.grid(row=2, column=1, sticky=W, columnspan=3)
def click(): # Callback function
guess = textEntry.get()
# Put all other processing here.
# Updating the image
img = PhotoImage(file=pic_list.pop()) # Get next image from list
hangman.configure(image=img) # Replace image in label
hangman.image = img # Keep reference to the new image
# Create button and associate it with the command callback function
guess_button = Button(window, text="Guess", width=5,
command=click).grid(row=3, column=2, sticky=W)
window.mainloop() # Will loop continously listening for buttonpress
Firstly, a while loop is not recommended for use when it comes to using tkinter module as the window would be running on the main thread. Logically, when using buttons, you can use if statements so that it won't trigger a specific part of code until lettersLeft > 0 and again == True. And the use of variable textEntry in a function is obviously not available to Python because there is no declaration of it. So you either pass the variable as argument or declare a global variable.
Here is what I would think of:
from tkinter import *
from random import choice
def get_wordlist():
return open("Hangman word list.txt", 'r').read().split("split by something here.")
class Hangman(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.title("Hangman")
self.master.configure(bg="black")
self.wordlist = get_wordlist()
self.p1 = PhotoImage(file="h1.gif")
self.word = choice(self.wordlist)
self.hidden_word = list("".join("_" for x in word))
self.wrong_guess = []
self.lives = 6
self.word_display = Label(window, text=str(*(hidden for hidden in hidden_word)), image=p1, bg="purple", fg="white")
self.word_display.grid(row=0, column=0, columnspan=4)
Label(window, text="Enter a letter: ", bg="gray", fg="purple", font="none 12 bold").grid(row=2, column=0, sticky=W)
self.entry = Entry(window, width=5, bg="white")
self.entry.grid(row=2, column=1, sticky="W")
self.guess = Button(window, text="Guess", command=lambda: button_action(self))
self.guess.grid()
self.again = False
def button_action(self):
user_input = self.entry.get()
if len(user_input) == len(word):
for i in range(len(word)):
if word[i] == user_input[i]:
self.hidden_word[i] = word[i]
if "_" not in self.hidden_word:
self.word_display.config(text="You won! The correct word was: " + self.word)
self.after(3000, self.quit())
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
if self.lives <= 0:
self.word_display.config(text="You lost! The correct word was: " + self.word)
self.master.after(3000, self.quit())
Please note 2 things:
Try not to create redundant variables
Before even asking a question, please do look on python tkinter docs.
Related
I have a Python file that when run, opens a window for simple addition practice. It asks the user for their input, and if the total is correct will output "Right!" and "Oops!" for incorrect. Below all of this is a counter that keeps track of the correct number out of the total. However, at the moment, those numbers both remain zero when user enters their input. What kind of changes would need to be made under the ClicktheButton1 function in order to get this program properly functioning? Thanks.
The output would end up looking like "2 out 4 correct" in the window, updating after each new problem is solved.
from tkinter import *
import random as rn
window = Tk()
window.geometry('350x350')
window.title("C200")
x = rn.randint(0,100)
y = rn.randint(0,100)
correct, incorrect = 0,0
myLabel = Label(window, text="{0}+{1}=".format(x,y), font=("Arial Bold", 15))
myLabel.grid(column=0, row=0)
myLable2 = Label(window, text = "",font=("Arial Bold", 15))
myLable2.grid(column=0, row=5)
mylabel3 = Label(window,text = "0 out of 0 correct",font=("Arial Bold", 15))
mylabel3.grid(column=0, row=10)
mytxt = Entry(window, width=12)
mytxt.grid(column=1,row=0)
def ClicktheButton1():
global x
global y
global correct
global incorrect
myguess = int(mytxt.get())
if x + y == myguess:
myLable2.configure(text = "Right!")
correct += 1
else:
myLable2.configure(text = "Oops!")
incorrect += 1
x = rn.randint(0,100)
y = rn.randint(0,100)
mytxt.focus()
mytxt.delete(0,END)
myLabel.configure(text = "{0}+{1}=".format(x,y))
btn1 = Button(window, text="check", command = ClicktheButton1)
btn1.grid(column=0, row=7)
def ClicktheButton2():
window.destroy()
btn1 = Button(window, text="Quit", command = ClicktheButton2)
btn1.grid(column=400, row=400)
window.mainloop()
You have to change text in mylabel3 in the same why as you change text in myLabel - and even in the same place. I don't know why you have problem with this.
myLabel.configure(text = "{0}+{1}=".format(x,y))
mylabel3.configure(text="{0} of {1} correct".format(correct, correct+incorrect))
I am super new to Python and programming in general. I'm messing around in tkinter trying to make a silly and simple program so I can get more comfortable with it.
What I am doing with my program is asking for the user's name, age, if they remember certain events, and if they feel old or not. Like I said, it is supposed to be a light hearted program just to put my skills to the test.
Now I wonder, how to display GUI message indicating which checkbutton(s) and radiobutton have been selected in tkinter in Python?
Here is the code and a screenshot. I'll include a screenshot of my results but I can get the name and age to work like it should but can't get the message to appear correctly in the GUI with the checkboxes or radio button.
from tkinter import *
class MyFrame(Frame):
def __init__(self):
Frame.__init__(self)
self.master.geometry("600x400")
self.master.title("How to tell if you're old")
self.event = NONE
self.old = NONE
self.grid()
#user name and age
self.prompt = Label(self, text="What's your name?")
self.prompt.grid(row=0, column=0, pady=5)
self.input_name = Entry(self)
self.input_name.grid(row=0, column=1, pady=5)
self.prompt = Label(self, text="How old are you?")
self.prompt.grid(row=2, column=0, pady=5)
self.input_age = Entry(self)
self.input_age.grid(row=2, column=1, pady=10)
#user asks user if they remember certain events
self.prompt = Label(self, text="Which of these events do"
"you remember (may select more than one)?")
self.prompt.grid(row=3, columnspan=5, pady=5)
self.wheel_event = IntVar()
self.check_wheel_event = Checkbutton(self, text="Invention of the wheel",
variable=self.wheel_event, command=self.set_response_event)
self.check_wheel_event.grid(row=4, column=0, padx=5)
self.firstFlight_event = IntVar()
self.check_firstFlight_event = Checkbutton(self, text="First flight",
variable=self.firstFlight_event, command=self.set_response_event)
self.check_firstFlight_event.grid(row=4, column=1, padx=5)
self.Berlin_Wall_event = IntVar()
self.check_Berlin_Wall_event = Checkbutton(self, text="Berlin Wall",
variable=self.Berlin_Wall_event, command=self.set_response_event)
self.check_Berlin_Wall_event.grid(row=4, column=2, padx=5)
self.millennium_event = IntVar()
self.check_millennium_event = Checkbutton(self, text="Millennium",
variable=self.millennium_event, command=self.set_response_event)
self.check_millennium_event.grid(row=4, column=3, padx=5)
#user answers if they think they're old and if they want to know how
# old they'll be in 10, 15, or 20 years
self.prompt = Label(self, text="Do you consider yourself old?")
self.prompt.grid(row=5, column=0, pady=5)
self.feel_old = IntVar()
self.feel_old.set(4)
self.not_sure_old = Radiobutton(self, text="Not sure",
variable=self.feel_old, value="0")
self.not_sure_old.grid(row=6, column=0)
self.no_old = Radiobutton(self, text="No",
variable=self.feel_old, value="1")
self.no_old.grid(row=6, column=1)
self.yes_old = Radiobutton(self, text="Yes",
variable=self.feel_old, value="2")
self.yes_old.grid(row=6, column=2)
#submit button
self.button_submit = Button(self, text='Submit',
command=self.submit_click)
self.button_submit.grid
self.button_submit.grid(row=9, column=3, padx=10)
self.my_name = StringVar()
self.message = Label(self, textvariable=self.my_name)
self.message.grid(columnspan=2, pady=10)
self.my_age = StringVar()
self.message = Label(self, textvariable=self.my_age)
self.message.grid(columnspan=2, pady=10)
#response
def set_response_event(self):
#remembering events
if self.wheel_event.get() == 1:
self.event = "wheel"
elif self.firstFlight_event.get() == 1:
self.event = "firstFlight"
elif self.Berlin_Wall_event.get() == 1:
self.event = "Berlin_Wall"
elif self.millennium_event.get() == 1:
self.event = "millennium"
def set_response_old(self):
#feeling old
if self.not_sure_old.get() == "0":
self.old = "not_sure_old"
elif self.no_old.get() == "1":
self.old = "no_old"
elif self.yes_old.get() == "2":
self.old = "yes_old"
def submit_click(self):
output_message = 'Well ' + self.input_name.get() + ', to begin with you are ' + self.input_age.get() + '.\n'
output_message += 'You remember the ' + self.event +'.\n'
output_message += 'This means you are ' + self.old + '.'
self.my_name.set(output_message)
frame05 = MyFrame()
frame05.mainloop()
Here is what I get:
I realize I'm probably doing this the hard way but I feel like I'm really close. Thank you for your help!
First off, you are never calling set_response_old(self) that I can tell. Secondly you are trying to compare strings to integers, which doesn't get caught in your if statements. Try rewriting the last two functions like this:
def set_response_old(self):
#feeling old
if self.feel_old.get() == 0:
self.old = "not sure old"
elif self.feel_old.get() == 1:
self.old = "no old"
elif self.feel_old.get() == 2:
self.old = "yes old"
def submit_click(self):
self.set_response_old()
output_message = 'Well ' + self.input_name.get() + ', to begin with you are ' + self.input_age.get() + '.\n'
output_message += 'You remember the ' + self.event + '.\n'
output_message += 'This means you are ' + self.old + '.'
self.my_name.set(output_message)
When I run this it outputs
This means you are yes old.
Which I think is what you were going for.
#EDIT
As for getting the list of remembered events to show...You can add self.events_remembered = [] to your __init__ section to create a place to store the data (it's not required to be in the init section as the code below would make it anyways, but it's good practice!) and then change your set_response function as such:
def set_response_event(self):
#remembering events
self.events_remembered = [] # reset each time we are determining pressed events (so we don't just keep adding duplicates, and also remove any unchecked boxes)
if self.wheel_event.get() == 1:
self.events_remembered.append("wheel")
if self.firstFlight_event.get() == 1:
self.events_remembered.append("firstFlight")
if self.Berlin_Wall_event.get() == 1:
self.events_remembered.append("Berlin Wall")
if self.millennium_event.get() == 1:
self.events_remembered.append("millennium")
You are correct in thinking that the if will only catch the first one, but there is no rule against having a series of if statements like shown!
Finally you can update your submit_click function to search for this information and display the formatted list
def submit_click(self):
self.set_response_old()
self.set_response_event() # use the function we just updated
print(self.events_remembered)
output_message = 'Well ' + self.input_name.get() + ', to begin with you are ' + self.input_age.get() + '.\n'
output_message += 'You remember the ' + ", ".join(self.events_remembered) + '.\n'
output_message += 'This means you are ' + self.old + '.'
self.my_name.set(output_message)
Here we use ", ".join(iterable_list) to convert our python list to a nice comma separated list instead!
If this solved your question I would appreciate if you could accept the answer by clicking the check mark next to the post! If you really just like me you can click to upvote me too XD
To get all the checkbox values to the output, make self.event attribute a list
def __init__self():
...
...
self.event=[]
and when you call the set_response_event function, append those string values to that list.
def set_response_event(self):
#remembering events
if self.wheel_event.get() == 1:
self.event.append("wheel")
elif self.firstFlight_event.get() == 1:
self.event.append("firstFlight")
elif self.Berlin_Wall_event.get() == 1:
self.event.append("Berlin_Wall")
elif self.millennium_event.get() == 1:
self.event.append("millennium")
Finally print the list using .join function
'You remember the ' + ', '.join(self.event) + '\n'
I'm trying to create a Hangman game GUI using Tkinter. I have fully working code apart from several things. I want to create a loop that would restart the game by button press or quit the game by pressing "no".
I also want for these buttons to appear in new window and close the window before.
I've removed not needed parts of the code so you would only see main problem area and main idea. To make it work you just need to type in "b" and then "o":
from Tkinter import *
item = "BOO"
oldString = "-" * (len(item))
blank = "-" * (len(item))
guesses = 10
def start():
winMain.destroy()
mainMenu()
def theWinner():
def end():
root.destroy()
def replay():
root.destroy()
mainMenu()
root = Tk()
root.title("HANGMAN GAME DEMO")
answer = Entry(root)
answer.insert(END, "You Won!!! Play again?")
answer.grid(row = 0, column = 0)
yesB=Button(root, text = "Yes", command = replay)
yesB.grid(row = 1, column = 0)
noB = Button(root, text = "Quit", command = end)
noB.grid(row = 1, column = 1)
root.mainloop()
def mainMenu():
def gameOn():
global guesses
global oldString
newString = ""
i = 0
x = len(item)
hanged = ""
readString = answerIn.get().upper()
winner = 1
if readString not in item:
guesses -= 1
elif readString in item:
while x > 0:
if item[i] != readString:
newString = newString + oldString[i]
elif item[i] == readString:
newString = newString + readString
i +=1
x -=1
oldString = newString
out.config(state=NORMAL)
out.delete(0,END)
out.insert(0,oldString);
out.config(state=DISABLED)
answerIn.delete(0,END)
if oldString == item:
win.destroy()
theWinner()
newString = ""
i=0
x=len(item)
answerIn.delete(0,END)
win = Tk()
win.geometry ("665x480")
win.title("HANGMAN GAME DEMO")
win.configure(background='LightBlue2')
#Display of the word user is trying to guess
guessWord = Entry(win, disabledbackground = "mint cream", disabledforeground = "black", font="helvetica 11 bold", width = 12, border = 2)
guessWord.grid(row=1, column=0, pady = 10, padx = 6, sticky = W)
guessWord.insert(END, "The word is: ")
guessWord.config(state = DISABLED)
#guessWord = Label(win, bg = "mint cream", font="helvetica 10 ", text = "The word you have to guess is: ")
guessWord.grid(row=1, column=0, pady = 10, padx = 9, sticky = W)
out = Entry(win, border = 2, font="helvetica 15 bold", width = 12, disabledforeground = "black", disabledbackground = "gold")
out.insert(0,blank);
out.config(state=DISABLED)
out.grid(row=1, column=0, pady = 10, padx = 200, sticky = W)
#Type in Window
answer = Entry(win, disabledbackground = "mint cream", disabledforeground = "black", font="helvetica 10", width = 21, border = 2)
answer.grid(row=2, column=0, pady = 10, padx = 8, sticky = W)
answer.insert(END,"Please type in the letter: ")
answer.config(state=DISABLED)
answerIn = Entry(win,width = 3, border = 2)
answerIn.focus_set()
answerIn.grid(row=2, column=0, pady = 10, padx = 200, sticky = W)
b = Button(win, text = "Enter",command = gameOn, bg = "chartreuse2", font="helvetica 10 bold",)
b.grid(row=2, column=0, pady = 10, padx = 200)
win.mainloop()
winMain = Tk()
winMain.title("HANGMAN GAME DEMO")
imageLabel = Label(winMain, text = "HELLO!")
imageLabel.pack()
winMain.after(1000, start)
winMain.mainloop()
If I press "no", I get the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1541, in __call__
return self.func(*args)
File "C:/Python27/8.py", line 69, in gameOn
answerIn.delete(0,END)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2509, in delete
self.tk.call(self._w, 'delete', first, last)
TclError: invalid command name ".94412392"
If I press "yes", it does not seem to restart the game from the start. It only lets me enter one character before bringing Win window again.
Where am I going wrong and is there a quick fix for this?
The error is because after destroying the window you want to delete the content in the entry widget. See this part
def mainMenu():
.......
.......
......
if oldString == item:
win.destroy()
theWinner()
# newString = ""
# i=0
# x=len(item)
# answerIn.delete(0,END)
You can see i commented that part you don't need it after closing the window when you do that the error wont pop up again.With regards to the game not starting it thing you should create another function with the same command for for it because
def replay():
root.destroy()
mainMenu()
it isn't working when you call it.I will also suggest you use Toplevel window rather than calling Tk and mainloop more than one.
check this link out [Toplevel documentation][1] .It hard for everyone to debug your code because you are creating several function under another function separate them.
You need to reset oldString when you end a game:
Replace
if oldString == item:
win.destroy()
theWinner()
With
if oldString == item:
win.destroy()
oldString='---'
theWinner()
And it should work (I have tested).
Without trying to solve your issue on your codebase I do recommend to switch the code to be class based, that way you are more in control and can easier keep references which are needed to make some of this gui-stuff work as expected. A bonus will be that you can ditch the globals you have as well.
There is an excellent py2 tkinter doc from where this minimal example is copied just to give an idea of the class based style of coding for gui's, which generally is the prefered way of doing it. You seem to be on py2, however if you're on py3 the docs works as well, you just have to keep track of the minor differences in the imports.
import Tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit', command=self.quit)
self.quitButton.grid()
app = Application()
app.master.title('Sample application')
app.mainloop()
When A user inputs a blank string of text I can either pop up a new input box which looks nasty or, like a webpage, direct the cursor back into the Entry() box
Unfortunately after searching I am still completely clueless as to how I can achieve this direction of the cursor.
My code looks like this-
import time
from tkinter import *
root = Tk()
##Encrypt and Decrypt
Master_Key = "0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#£$%&'()*+,-./:;?#[\\]^_`{|}~\t\n\r\x0b\x0c"
def Encrypt(User_Input, Key):
Output = ""
for i in range(len(User_Input)):
Ref_For_Output = Master_Key.index(User_Input[i]) + Master_Key.index(Key[i])
if Ref_For_Output >= len(Master_Key):
Ref_For_Output -= len(Master_Key)
Output += Master_Key[Ref_For_Output]
return Output
def Decrypt(User_Input, Key):
Output = ""
for i in range(len(User_Input)):
Ref_For_Output = Master_Key.index(User_Input[i]) - Master_Key.index(Key[i])
if Ref_For_Output < 0:
Ref_For_Output += len(Master_Key)
Output += Master_Key[Ref_For_Output]
return Output
##def popup():
## main = Tk()
## Label1 = Label(main, text="Enter a new key: ")
## Label1.grid(row=0, column=0)
## New_Key_Box = Entry(main, bg="grey")
## New_Key_Box.grid(row=1, column=0)
##
## Ok = Button(main, text="OK", command=Set_Key(New_Key_Box.get()))
##
## Ok.grid(row=2, column=0)
## if
## main.geometry("100x300")
## main.mainloop()
## return New_Key_Box.get()
class MyDialog:
def __init__(self, parent):
top = self.top = Toplevel(parent)
Label(top, text="Value").pack()
self.e = Entry(top)
self.e.pack(padx=5)
b = Button(top, text="OK", command=self.ok)
b.pack(pady=5)
def ok(self):
print( "value is" + self.e.get())
return self.e.get()
self.top.destroy()
def Compatibility(User_Input, Key):
while Key == "":
root = Tk()
Button(root, text="Hello!").pack()
root.update()
d = MyDialog(root)
print(d.ok(Key))
root.wait_window(d.top)
Temp = 0
while len(Key) < len(User_Input):
Key += (Key[Temp])
Temp += 1
return Key
##Layout
root.title("A451 CAM2")
root.geometry("270x80")
Label1 = Label(root, text="Input: ")
Label1.grid(row=0, column=0, padx=10)
Label2 = Label(root, text="Key: ")
Label2.grid(row=1, column=0, padx=10)
Input_Box = Entry(root, bg="grey")
Input_Box.grid(row=0, column=1)
Key_Box = Entry(root, bg="grey")
Key_Box.grid(row=1, column=1)
def Encrypt_Button_Press():
User_Input = Input_Box.get()
Key = Compatibility(User_Input, Key_Box.get())
print(User_Input)
root.clipboard_append(Encrypt(User_Input, Key))
Encrypt_Button.configure(text="Encrypting")
messagebox.showinfo("Complete", "Your encrypted text is: \n" + Encrypt(User_Input, Key) + "\n The text has been added to your clipboard.")
Encrypt_Button.configure(text="Encrypt")
#popup()
def Decrypt_Button_Press():
User_Input = Input_Box.get()
Key = Key = Compatibility(User_Input, Key_Box.get())
print(User_Input)
root.clipboard_append(Decrypt(User_Input, Key))
Decrypt_Button.configure(text="Decrypting")
messagebox.showinfo("Complete", "Your Decrypted text is: \n" + Decrypt(User_Input, Key) + "\n The text has been added to your clipboard.")
Decrypt_Button.configure(text="Decrypt")
Encrypt_Button = Button(text="Encrypt", command=Encrypt_Button_Press)
Encrypt_Button.grid(row=0, column=3, padx=10)
Decrypt_Button = Button(text="Decrypt", command=Decrypt_Button_Press)
Decrypt_Button.grid(row=1, column = 3, padx=10)
root.mainloop()
In the compatibility function I am wanting to change the while Key == "":
to pop-up a message (that's easy) and to direct the cursor back to the Key_Box( I may also make it change to red or something)
So- does anyone know how I can achieve redirection of the cursor?
Edit:I am not sure whether this is included anywhere in Tkinter, I can use tab to switch between Entry() boxes so I assume that they function in roughly the same way as other entry boxes across different platforms.
You could call .focus() on the entry? It won't move the cursor, but the user would be able to just start typing away in the entry box as if they had clicked in it.
I would like to ask how would I go about maybe creating a 'LIVE' text box in python? This program is a simulator for a vending machine (code below). I want there to be a text box showing a live credit update How do you do that in tkinter?
For Example: Say there is a box for credit with 0 inside it in the middle of the window. When the 10p button is pressed the box for credit should change from '0' to '0.10'.
Is it possible to do thit in tkinter and python 3.3.2?
Thank you in advance!
import sys
import tkinter as tk
credit = 0
choice = 0
credit1 = 0
coins = 0
prices = [200,150,160,50,90]
item = 0
i = 0
temp=0
n=0
choice1 = 0
choice2 = 0
credit1 = 0
coins = 0
prices = [200,150,160,50,90]
item = 0
i = 0
temp=0
n=0
choice1 = 0
choice2 = 0
def addTENp():
global credit
credit+=0.10
def addTWENTYp():
global credit
credit+=0.20
def addFIFTYp():
global credit
credit+=0.50
def addPOUND():
global credit
credit+=1.00
def insert():
insert = Tk()
insert.geometry("480x360")
iLabel = Label(insert, text="Enter coins.[Press Buttons]").grid(row=1, column=1)
tenbutton = Button(insert, text="10p", command = addTENp).grid(row=2, column=1)
twentybutton = Button(insert, text="20p", command = addTWENTYp).grid(row=3, column=1)
fiftybutton = Button(insert, text="50p", command = addFIFTYp).grid(row=4, column=1)
poundbutton = Button(insert, text="£1", command = addPOUND).grid(row=5, column=1)
insert()
Sure you can! Just add another label to the frame, and update the text attribute whenever one of your add functions is called. Also, you can simplify that code, using one add function for all the different amounts.
def main():
frame = Tk()
frame.geometry("480x360")
Label(frame, text="Enter coins.[Press Buttons]").grid(row=1, column=1)
display = Label(frame, text="") # we need this Label as a variable!
display.grid(row=2, column=1)
def add(amount):
global credit
credit += amount
display.configure(text="%.2f" % credit)
Button(frame, text="10p", command=lambda: add(.1)).grid(row=3, column=1)
Button(frame, text="20p", command=lambda: add(.2)).grid(row=4, column=1)
Button(frame, text="50p", command=lambda: add(.5)).grid(row=5, column=1)
Button(frame, text="P1", command=lambda: add(1.)).grid(row=6, column=1)
frame.mainloop()
main()
Some more points:
note that you define many of your variables twice
you should not give a variable the same name as a function, as this will shadow the function
probably just a copy paste error, but you forgot to call mainloop and your tkinter import is inconsistent with the way you use the classes (without tk prefix)
you can do the layout right after creating the GUI elements, but note that in this case not the GUI element will be bound to the variable, but the result of the layouting function, which is None
Borrowing a framework from tobias_k's excellent answer, I would recommend you use a DoubleVar instead.
from tkinter import ttk
import tkinter as tk
def main():
frame = Tk()
frame.geometry("480x360")
credit = tk.DoubleVar(frame, value=0)
# credit = tk.StringVar(frame, value="0")
ttk.Label(frame, textvariable = credit).pack()
def add_credit(amt):
global credit
credit.set(credit.get() + amt)
# new_credit = str(int(credit.get().replace(".",""))+amt)
# credit.set(new_credit[:-2]+"."+new_credit[-2:])
ttk.Button(frame, text="10p", command = lambda: add_credit(0.1)).pack()
# ttk.Button(frame, text="10p", command = lambda: add_credit(10)).pack()
ttk.Button(frame, text="20p", command = lambda: add_credit(0.2)).pack()
# ttk.Button(frame, text="20p", command = lambda: add_credit(20)).pack()
ttk.Button(frame, text="50p", command = lambda: add_credit(0.5)).pack()
# ttk.Button(frame, text="50p", command = lambda: add_credit(50)).pack()
ttk.Button(frame, text="P1", command = lambda: add_credit(1.0)).pack()
# ttk.Button(frame, text="P1", command = lambda: add_credit(100)).pack()
frame.mainloop()
The comments in that code is an alternate implementation that will work better, if only just. This will guarantee you won't have any strange floating-point errors in your code.