Reputation: 25
I'm writing a connect-4 game with Tkinter, and I would to present several menu options to the user during the course of the game.
The problem is that the menus tend to be presented together, as in the piece of code below. For example, in present_player_choice(), I'd like to present a menu for playerA, get an answer, and then present a menu for playerB. This is not that crucial here, but it's a problem I keep running across.
after() does not seem to be the answer, as I do not want the menu to disappear after a certain space of time, but rather to disappear after the user has submitted an answer.
Also: In writing an 'ok' button for the menu, I've used 'quit.' But quit closes the entire widget! I want the gui to continue, and simply the menu to close, not the entire GUI!
I know these questions sound rather clueless, but I've been working on this for a while and am genuinely confused. Thanks in advance for any help.
from tkinter import *
class GUI:
def __init__(self, root):
self.__root = root
self.__player_A = None
self.__player_B = None
def assign_player(self, player, identity):
if player == "player A":
self.__player_A = identity
elif player == "player B":
self.__player_B = identity
print("Player A is: " + str(self.__player_A))
print("Player B is: " + str(self.__player_B))
def present_player_choice(self):
self.ask_choose_player("player A")
self.ask_choose_player("player B")
Button(self.__root, text="OK", command=quit).pack(anchor=W)
def ask_choose_player(self, player):
Label(self.__root, text="Who would you like to play " + player + "?").pack(anchor=W)
var = IntVar()
Radiobutton(self.__root, text="human", variable=var,
command=lambda:self.assign_player(player, HUMAN), value=1).pack(anchor=W)
Radiobutton(self.__root, text="computer", variable=var,
command=lambda:self.assign_player(player, COMPUTER), value=2).pack(anchor=W)
if __name__ == '__main__':
root = Tk()
gui = GUI(root)
gui.present_player_choice()
mainloop()
Upvotes: 1
Views: 96
Reputation: 15236
The quickest way to do this is to add a Frame
to your class that we can use to reset the content and then move the call for player B into a condition in the assign_player
method to update the frame for player B when a selection is chosen.
You may also want to add tristatevalue=0
to your radio buttons so that there is no default selection.
Example:
import tkinter as tk
class GUI:
def __init__(self, root):
self.__root = root
self.__player_A = None
self.__player_B = None
self.frame = None
def assign_player(self, player, identity):
if player == "player A":
self.__player_A = identity
print("Player A is: " + str(self.__player_A))
self.ask_choose_player("player B")
tk.Button(self.__root, text="OK", command=quit).pack(anchor=tk.W)
elif player == "player B":
self.__player_B = identity
print("Player B is: " + str(self.__player_B))
self.frame.destroy()
def present_player_choice(self):
self.ask_choose_player("player A")
def ask_choose_player(self, player):
if self.frame is None:
self.frame = tk.Frame(self.__root)
else:
self.frame.destroy()
self.frame = tk.Frame(self.__root)
self.frame.pack(fill='both', expand=1)
tk.Label(self.frame, text="Who would you like to play " + player + "?").pack(anchor=tk.W)
var = tk.IntVar()
tk.Radiobutton(self.frame, text="human", variable=var, tristatevalue=0,
command=lambda: self.assign_player(player, 'human'), value=1).pack(anchor=tk.W)
tk.Radiobutton(self.frame, text="computer", variable=var, tristatevalue=0,
command=lambda: self.assign_player(player, 'pc'), value=2).pack(anchor=tk.W)
if __name__ == '__main__':
root = tk.Tk()
gui = GUI(root)
gui.present_player_choice()
root.mainloop()
Before/after selection:
Upvotes: 1