window destruction error in Tkinter - python

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()

Related

Tkinter problem creating button to collect text from user

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.

Python Tkinterprogramm import to a new file throws a error

i have a problem with the user-output of my tkinter gui.
First of all it works, but there is a huge problem with the import to a new py file. It throws a Error ().
Traceback (most recent call last):
File "F:\Python_Projekt\Übung\Plus\test.py", line 4, in <module>
tk = own.get_start()
File "F:\Python_Projekt\Übung\Plus\plus_window_pack2.py", line 31, in get_start
sel = ListBox1.curselection()
File "C:\Users\nox\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 2782, in curselection
return self._getints(self.tk.call(self._w, 'curselection')) or ()
_tkinter.TclError: invalid command name ".!frame.!frame.!listbox"
I know there is a problem with my ListBox but i have no clue how to handle it. I need the used output for my new script. So i could work with it.
from tkinter import*
import tkinter as tk
window = Tk()
rahmen1 = Frame(master = window) #, bg='black'
rahmen1.pack(side='top', padx=5, pady=5)
rahmen2 = Frame(master = rahmen1) #, bg= 'yellow'
rahmen2.pack(side='left', padx=5, pady=5)
def get_start():
selection=ListBox1.curselection()
picked = selection[0]
used = ListBox1.get(picked) #-------user-input
print(used)
return used
####################----------------------------------------------------
List = ['Dax','Dow','EUR/USD', 'Gold', 'Silber','EUR/JPY','USD/JPY']
scrollbar1 = Scrollbar(rahmen2) # ,bg='green'
scrollbar1.pack(padx = 1,side = 'right',fill=Y)
ListBox1 = Listbox(rahmen2,exportselection = False)
ListBox1.config( yscrollcommand = scrollbar1.set, width = 40)
scrollbar1.config( command = ListBox1.yview) # ,bg='blue'
for i in List:
ListBox1.insert(tk.END, str(i))
ListBox1.pack(padx = 1,)
###################------------------------------------------------
Button1 = Button(rahmen2,text='Get Data', font = 'bold')
Button1.config (width=40, height = 3, command = get_start)
Button1.pack( )
window.mainloop()
I changed the code to get the important part. For a better understanding of my problem.
if i want to get the user-input it thorw's me the error.
Try this. I have added a simple check to make sure something's selected (I'm not sure what the error at the top of your question's about though):
def get_start():
selection=ListBox1.curselection()
if len (selection) != 0:
picked = selection[0]
used = ListBox1.get(picked) #-------user-input
print(used)
return used
EDIT:
This checks every x seconds (defined by UPDATE_TIME) for checkbox updates
UPDATE_TIME = 0.1
from tkinter import*
import tkinter as tk
import threading, time
window = Tk()
rahmen1 = Frame(master = window) #, bg='black'
rahmen1.pack(side='top', padx=5, pady=5)
rahmen2 = Frame(master = rahmen1) #, bg= 'yellow'
rahmen2.pack(side='left', padx=5, pady=5)
def get_start():
print (previous)
return previous
def get_update ():
global previous
try:
while True:
selection=ListBox1.curselection()
if len (selection) == 0: previous = None
else:
picked = selection[0]
previous = ListBox1.get(picked) #-------user-input
time.sleep (UPDATE_TIME)
except: pass
####################----------------------------------------------------
List = ['Dax','Dow','EUR/USD', 'Gold', 'Silber','EUR/JPY','USD/JPY']
scrollbar1 = Scrollbar(rahmen2) # ,bg='green'
scrollbar1.pack(padx = 1,side = 'right',fill=Y)
ListBox1 = Listbox(rahmen2,exportselection = False)
ListBox1.config( yscrollcommand = scrollbar1.set, width = 40)
scrollbar1.config( command = ListBox1.yview) # ,bg='blue'
for i in List:
ListBox1.insert(tk.END, str(i))
ListBox1.pack(padx = 1,)
###################------------------------------------------------
Button1 = Button(rahmen2,text='Get Data', font = 'bold')
Button1.config (width=40, height = 3, command = get_start)
Button1.pack ()
threading.Thread (target = get_update).start ()
window.mainloop()

How to display output of print() in GUI python

I am new in creating GUI. I am doing it in Python with Tkinter. In my program I calculate following characteristics
def my_myfunction():
my code ...
print("Centroid:", centroid_x, centroid_y)
print("Area:", area)
print("Angle:", angle)
I would like to ask for any help/tips how to display those values in GUI window or how to save them in .txt file so that I can call them in my GUI
Thanks in advance
Tkinter is easy and an easy way to do a GUI, but sometimes it can be frustrating. But you should have read the docs before.
However, you can do in this way.
from tkinter import *
yourData = "My text here"
root = Tk()
frame = Frame(root, width=100, height=100)
frame.pack()
lab = Label(frame,text=yourData)
lab.pack()
root.mainloop()
There are several ways to display the results of any operation in tkiner.
You can use Label, Entry, Text, or even pop up messages boxes. There are some other options but these will probably be what you are looking for.
Take a look at the below example.
I have a simple adding program that will take 2 numbers and add them together. It will display the results in each kind of field you can use as an output in tkinter.
import tkinter as tk
from tkinter import messagebox
class App(tk.Frame):
def __init__(self, master):
self.master = master
lbl1 = tk.Label(self.master, text = "Enter 2 numbers to be added \ntogether and click submit")
lbl1.grid(row = 0, column = 0, columnspan = 3)
self.entry1 = tk.Entry(self.master, width = 5)
self.entry1.grid(row = 1, column = 0)
self.lbl2 = tk.Label(self.master, text = "+")
self.lbl2.grid(row = 1, column = 1)
self.entry2 = tk.Entry(self.master, width = 5)
self.entry2.grid(row = 1, column = 2)
btn1 = tk.Button(self.master, text = "Submit", command = self.add_numbers)
btn1.grid(row = 2, column = 1)
self.lbl3 = tk.Label(self.master, text = "Sum = ")
self.lbl3.grid(row = 3, column = 1)
self.entry3 = tk.Entry(self.master, width = 10)
self.entry3.grid(row = 4, column = 1)
self.text1 = tk.Text(self.master, height = 1, width = 10)
self.text1.grid(row = 5, column = 1)
def add_numbers(self):
x = self.entry1.get()
y = self.entry2.get()
if x != "" and y != "":
sumxy = int(x) + int(y)
self.lbl3.config(text = "Sum = {}".format(sumxy))
self.entry3.delete(0, "end")
self.entry3.insert(0, sumxy)
self.text1.delete(1.0, "end")
self.text1.insert(1.0, sumxy)
messagebox.showinfo("Sum of {} and {}".format(x,y),
"Sum of {} and {} = {}".format(x, y, sumxy))
if __name__ == "__main__":
root = tk.Tk()
myapp = App(root)
root.mainloop()

tkinter button double use

I'm new here and new in PY, I'm trying to write a simple GUI with Tkinter (py 2.7.10) where there are two buttons: the first one starts printing stuff and the second one quits.
I'd like the first button to change the text after the first click from "START" to "STOP" and of course to stop the loop, so I can pause instead of closing and reopen every time.
Also feel free to give any advice to improve it :)
I hope it's clear, here is the code.
import random, time
from Tkinter import *
START, STOP = "start", "stop"
class AppBase:
def __init__(self, root):
self.myRoot = root
self.frame1 = Frame(root)
self.frame1["background"] = "LightSteelBlue"
self.frame1.pack()
self.delay = Scale(self.frame1, from_=100, to=0)
self.delay.pack(side = LEFT, padx=5, pady=15)
self.label0 = Label(self.frame1, text="Notes", background="LightSteelBlue", foreground="darkblue")
self.label0.pack(padx=5, pady=15)
self.label1 = Label(self.frame1, text="NOTE", background="LightSteelBlue", foreground="SteelBlue")
self.label1.pack(padx=30, pady=10)
self.label2 = Label(self.frame1, text="STRING", background="LightSteelBlue", foreground="SteelBlue")
self.label2.pack(padx=30, pady=7)
self.label3 = Label(self.frame1, text="FINGER", background="LightSteelBlue", foreground="SteelBlue")
self.label3.pack(padx=30, pady=7)
self.puls1 = Button(self.frame1)
self.puls1.configure(text = "Start", background = "CadetBlue", borderwidth = 3, command = self.generate_notes)
self.puls1.pack(side = LEFT, padx=5, pady=15)
self.puls2 = Button(self.frame1)
self.puls2.configure(text = "Exit", background = "CadetBlue", borderwidth = 3)
self.puls2.pack(side = LEFT, padx=5, pady=15)
self.puls2.bind("<Button-1>", self.close_all)
self.notes_process=1
def generate_notes(self):
self.notes = ['DO','DO#','RE','RE#','MI','MI#','FA','FA#','SOL','SOL#','LA','LA#','SI','SI#']
self.strings = ['1^ corda','2^ corda','3^ corda','4^ corda','5^ corda','6^ corda']
self.fingers = ['Indice','Medio','Anulare','Mignolo']
self.note = random.randrange(0, len(self.notes))
self.string = random.randrange(0, len(self.strings))
self.finger = random.randrange(0, len(self.fingers))
self.timer=self.delay.get()
if self.timer == '':
self.timer = 500
elif int(self.timer) < 1:
self.timer = 500
else:
self.timer=int(self.delay.get())*100
self.label1["text"] = self.notes[self.note]
self.label2["text"] = self.strings[self.string]
self.label3["text"] = self.fingers[self.finger]
self.myRoot.after(self.timer, self.generate_notes)
def close_all(self, evento):
self.myRoot.destroy()
self.myRoot.quit()
def main():
master = Tk()
master.title("Notes")
appBase = AppBase(master)
master.mainloop()
main()
I found a solution, thanks to everybody for their help and of course if you want to keep talking about different and (sure) better way to do, you are more than welcome!
Here my solution:
step 1, add this to the button:
self.puls1.bind("<Button-1>", self.puls1Press1)
step 2, add a new variable:
self.active = True
step 3, create a new function:
def puls1Press1(self, evento):
if self.puls1["text"] == "Start":
self.puls1["text"] = "Stop"
self.active = True
else:
self.puls1["text"] = "Start"
self.active = False
step 4, modify the function that I want to stop:
def generate_notes(self):
if self.active == True:
[some code]
[some code]
else:
return
You need to save the return value of the after, so that you can use it when you cancel the loop using after_cancel(the_return_value_of_after).
def generate_notes(self):
if self.puls1['text'] == 'Start':
# Change button text to Stop, and call the original loop function
self.puls1['text'] = 'Stop'
self._generate_notes()
else:
# cancel timer
self.puls1['text'] = 'Start'
self.myRoot.after_cancel(self.timer_handle)
def _generate_notes(self):
...(old codes)..
self.timer_handle = self.myRoot.after(self.timer, self._generate_notes)
StringVar() from variable class can be used to update text as well as a looping condition. Example code:
ButtonText=StringVar()
ButtonText.set("START")
button1 = tkinter.Button(self.frame1, text=ButtonText, width=25, command= lambda: do_something(ButtonText))
Elsewhere where you are looping check for the value of the variable:
My_Loop():
if(ButtonText.get()=="STOP"):
break
else:
#some print statements
Now in function do_something(ButtonText), which will be called after each button press, change the string to "STOP" or vice versa :
do_something(ButtonText):
if(ButtonText.get()=="START): #Change text
ButtonText.set("STOP")
else:
ButtonText.set("START") #Change text and call function to loop again
My_Loop()
Hope this helps.

Python Tkinter: Loop The Computer's Turn A Certain Amount of Times

I'm writing a program for a dice game (Pig). In the game, the player will roll a d6 until they decide to hold their score (passing to the computer) or until they roll a 1, which will automatically make it the computer's turn.
The issue I'm having is that I need the function for the computer's turn to loop ten times. I want the computer to roll the die ten times, where it will either roll a one and pass back to the player or it will hold after ten rolls. How do I get the computer to roll the die ten times without using a loop inside of Tk?
Here's the code:
from Tkinter import *
from random import *
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.headerFont = ("courier new", "16", "bold")
self.title("Pig, The Dice Game")
self.headers()
self.rollDie()
def headers(self):
Label(self, text = "Instructions", font = self.headerFont).grid(columnspan = 4)
Label(self, text = "Text", font = self.headerFont).grid(row = 1, columnspan = 4)
Label(self).grid(row = 1, columnspan = 4)
Label(self, text = "The Game of Pig", font = self.headerFont).grid(row = 2, columnspan = 4)
def rollDie(self):
self.btnRoll = Button(self, text = "Roll The Die")
self.btnRoll["state"] = 'active'
self.btnRoll.grid(row = 3, columnspan = 4)
self.btnRoll["command"] = self.playerTurn
self.btnHold = Button(self, text = "Hold")
self.btnHold["state"]= 'active'
self.btnHold.grid(row = 4, columnspan = 4)
self.btnHold["command"] = self.compTurn
self.btnPass = Button(self, text = "Pass")
self.btnPass.grid(row = 5, columnspan = 4)
self.btnPass["command"] = self.compTurn
Label(self, text = "You Rolled:").grid(row = 6, column = 0)
self.lblYouRolled = Label(self, bg = "#fff", anchor = "w", relief = "groove")
self.lblYouRolled.grid(row = 6, column = 1, columnspan = 1, sticky = "we")
Label(self, text = "Options:").grid(row = 7, column = 0)
self.lblOptions = Label(self, bg = "#fff", anchor = "w", relief = "groove")
self.lblOptions.grid(row = 7, column = 1, sticky = "we")
Label(self, text = "Player One Turn Score:").grid(row = 8, column = 0)
self.lblPlayerOneTurnScore = Label(self, bg = "#fff", anchor = "w", relief = "groove")
self.lblPlayerOneTurnScore.grid(row = 8, column = 1, sticky = "we")
def playerTurn(self):
self.oneTurnTotal = [0]
self.oneRoll = randint(1,6)
self.btnHold["state"] = 'active'
self.lblYouRolled["text"] = self.oneRoll
if self.oneRoll != 1:
self.oneTurnTotal.append(self.oneRoll)
self.lblOptions["text"] = "Roll again, or hold and pass the dice to Player Two."
else:
self.lblOptions["text"] = "You rolled a 1! Click 'Pass' to pass your turn to the computer."
self.oneTurnTotal = [0]
self.btnRoll["state"] = 'disabled'
self.btnHold["state"] = 'disabled'
def calculatePlayerOneTurnScore(self):
turnScore = sum(self.oneTurnTotal)
self.lblPlayerOneTurnScore["text"] = turnScore
def compTurn(self):
self.compTurnTotal = [0]
self.compRoll = randint(1,6)
self.lblYouRolled["text"] = self.compRoll
if self.compRoll != 1:
self.compTurnTotal.append(self.compRoll)
self.lblOptions["text"] = "The computer will roll again."
else:
self.lblOptions["text"] = "The computer rolled a 1! Its turn has ended."
self.compTurnTotal = [0]
self.btnRoll["state"] = 'active'
def calculatePlayerTwoTurnScore(self):
turnScore = sum(self.twoTurnTotal)
self.lblPlayerTwoTurnScore["text"] = turnScore
def main():
app = App()
app.mainloop()
if __name__ == "__main__":
main()
You could make the dicerolling a toplevel widget and then have your root "wait_window" for the rolling widget to complete. Create a function inside the toplevel widget that generates the roll and call it ten times
EXAMPLE
from Tkinter import *
yourscorevalue=12
cpuscorevalue=10
class dice:
def __init__(self,parent):
rollcount=0
top=self.top=Toplevel(parent)
while 1:
roll=self.diceroll()
rollcount+=1
if rollcount==10 or roll==1:
break
def diceroll(self):
#Random Dice Roll code
class dicegame:
def __init__(self):
self.root=Tk()
self.root.title('Dicerolling Game')
Label(self.root, text='Your Score').grid(column=0,row=0,sticky='ew')
Label(self.root, text=yourscorevalue, background='black',foreground='red').grid(column=1,row=0,sticky='ew')
Label(self.root, text='Computer Score').grid(column=0,row=1,sticky='ew')
Label(self.root, text=cpuscorevalue, background='black',foreground='red').grid(column=1,row=1,sticky='ew')
b=Button(self.root, text='Roll The Dice', command=self.roll).grid(column=0,row=2,sticky='ew')
c=Button(self.root, text="Done", command=self.root.destroy).grid(column=1,row=2,sticky='ew')
mainloop()
def roll(self):
d=dice(self.root)
self.root.wait_window(d.top)

Categories