使用tkinter.grid()启用/禁用多个Entry小部件

时间:2013-05-03 19:27:38

标签: python tkinter

我编写了一个python扫雷游戏菜单,允许玩家输入自定义行,列和我的计数。我想这样做,以便单击简单,中等或硬单选按钮将禁用所有三个条目小部件,单击自定义单选按钮将启用所有三个。

我的代码:

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)

执行代码会给我以下窗口,没有错误:http://i.imgur.com/aNItO0f.png

但是,当我选择一个单选按钮时,控制台会输出错误:

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

看来这个错误是由于没有传入E_row值引起的,但是我已经使用.pack()而不是grid来使用该方法。通常我只是切换到.pack();但是,由于我的游戏的其余部分是.grid()而不是.pack(),我仍然坚持使用.grid作为菜单。我在这里缺少什么?

2 个答案:

答案 0 :(得分:1)

这个比你想象的要简单得多!实际上,您根本不需要更改代码。问题是您将T_row,T_col等分配给每个窗口小部件的grid(row=1,column=2)方法的返回值,即无。相反,只需将该语句分为两行:

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)

答案 1 :(得分:0)

扩展blackbirdkim的答案,Tkinter(与python中的许多其他东西不同)在窗体管理器之类的返回值中不一定直观(.grid总是返回None而不是父窗口小部件)。不可避免地会出现像这样的奇怪事情的雷区(同样菜单的add_checkbutton很快就会浮现在脑海中,因为它没有给你一个检查按钮的相同底层访问权限)。它支付(至少在Tkinter中)检查每个方法返回的确切内容。