1

我正在为 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() 而不是网格的方法。通常我会切换到 .pack(); 但是,由于我的游戏的其余部分是 .grid() 而不是 .pack() 我也被困在菜单中使用 .grid 。我在这里想念什么?

4

2 回答 2

1

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

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)
于 2014-04-21T17:56:25.697 回答
0

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

于 2014-04-21T18:28:35.493 回答