Reputation: 19
I'm coding a menu for a python minesweeper game that will allow players to enter in custom row, column and mine counts. I want to make it so that clicking the easy, medium, or hard radio buttons will disable all three entry widgets, and clicking the custom radiobutton will enable all three.
My code:
from tkinter import *
def customDisable():
E_row.configure(state='disabled')
E_row.update()
E_col.configure(state='disabled')
E_col.update()
E_mine.configure(state='disabled')
E_mine.update()
def customEnable():
E_row.configure(state='normal')
E_row.update()
E_col.configure(state='normal')
E_col.update()
E_mine.configure(state='normal')
E_mine.update()
menu=Tk()
menu.title('Pysweeper V 1.0')
ms=Canvas(menu,width=5,height=5)
ms.data={}
menu.resizable(0,0)
T_row=Label(menu,text='Rows:',anchor=E).grid(row=1,column=2)
T_col=Label(menu,text='Columns:',anchor=E).grid(row=2,column=2)
T_mine=Label(menu,text='Mines:',anchor=E).grid(row=3,column=2)
E_row=Entry(menu,state='normal').grid(row=1,column=3)
E_col=Entry(menu,state='normal').grid(row=2,column=3)
E_mine=Entry(menu,state='normal').grid(row=3,column=3)
dif=IntVar()
RB_easy=Radiobutton(menu, text='Easy',anchor=W,variable=dif,value=1,command=customDisable).grid(row=1,column=1,rowspan=2)
RB_med=Radiobutton(menu, text='Medium',anchor=W,variable=dif,value=2,command=customDisable).grid(row=3,column=1,rowspan=2)
RB_hard=Radiobutton(menu, text='Hard',anchor=W,variable=dif,value=3,command=customDisable).grid(row=5,column=1,rowspan=2)
RB_cust=Radiobutton(menu, text='Custom game',variable=dif,value=4,command=customEnable).grid(row=7,column=1)
Executing the code gives me the following window with no errors: https://i.sstatic.net/08N8W.png
However, when I select a radio button, the console prints an error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Python33\Minesweeper.py", line 212, in customDisable
E_row.configure(state='disabled')
NameError: global name 'E_row' is not defined
It appears that this error is caused by not passing in the E_row values, but I've gotten the method to work using .pack() instead of grid. Normally I'd just switch to .pack(); however, since the rest of my game is .grid() instead of .pack() I'm stuck using .grid for the menu as well. What am I missing here?
Upvotes: 1
Views: 3340
Reputation: 78
Expanding on blackbirdkim's answer, Tkinter (unlike a lot of other things out there in python) is not necessarily intuitive in the return value of things like window managers (.grid always returns None instead of the parent widget). There's inevitably a minefield of strange things like this (also menu's add_checkbutton quickly comes to mind for not giving you the same underlying access a checkbutton would). It pays (at least in Tkinter) to check what exactly each method returns.
Upvotes: 0
Reputation: 538
This one is much simpler than you may think! In fact, you don't have to change your code much at all. The issue is that you're assigning T_row, T_col, etc. to the return value of each widget's grid(row=1,column=2)
method, which is None. Instead, just separate the statement into two lines:
T_row=Label(menu,text='Rows:',anchor=E)
T_row.grid(row=1,column=2)
T_col=Label(menu,text='Columns:',anchor=E)
T_col.grid(row=2,column=2)
T_mine=Label(menu,text='Mines:',anchor=E)
T_mine.grid(row=3,column=2)
E_row=Entry(menu,state='normal')
E_row.grid(row=1,column=3)
E_col=Entry(menu,state='normal')
E_col.grid(row=2,column=3)
E_mine=Entry(menu,state='normal')
E_mine.grid(row=3,column=3)
Upvotes: 1