如何使用复选框窗口小部件将条目窗口小部件状态从禁用更改为未禁用?

时间:2016-12-07 04:12:42

标签: python tkinter state tkinter-entry

我正在使用tkinter 8.6和python 3.5.2并且我尝试创建一个GUI,这样当我单击一个复选框时它允许用户在输入框中写入内容。但是我收到了一个错误。以下是我的代码。

from tkinter import *
from tkinter import ttk

def quit():
    mainframe.quit()

#Write in Function
def write():
    write_in.state(['!disabled']) #Getting Error Here

root = Tk()
root.title("Voting Booth")

#Global variables
var = StringVar()

#Create main widget
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

#Additional widgets
ttk.Label(mainframe, textvariable=var, font=('bold')).grid(column=2, row=0)
vote = ttk.Button(mainframe, text="Vote", command = quit).grid(column=4, row=5, sticky=E)
don_box = ttk.Checkbutton(mainframe, text="Donald Trump").grid(column=2, row=1, sticky=W)
stein_box = ttk.Checkbutton(mainframe, text="Jill Stein").grid(column=2, row=3, sticky=W)
write_box = ttk.Checkbutton(mainframe, text="Write in:", command = write).grid(column=2, row=4, sticky=W)
write_in = ttk.Entry(mainframe, width = 20, state=DISABLED).grid(column=3, row=4, sticky=W)

#Setting variables and widgets
var.set("Presidential Nominees")

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

root.mainloop();

但是,当我单击write_in复选框时,我收到以下错误:

" File "/usr/lib/python3.5/tkinter/__init__.py", line 1553, in __call__
return self.func(*args)
File "./booth_gui.py", line 13, in write
write_in.state(['!disabled'])
AttributeError: 'NoneType' object has no attribute 'state' "

2 个答案:

答案 0 :(得分:1)

这是一个完整的解决方案:

import tkinter
from tkinter import ttk

class MyApp:
    def __init__(self):
        self.root = tkinter.Tk()
        self.root.title('Voting Booth')

        self.labelvar = tkinter.StringVar()
        self.votevar = tkinter.StringVar()
        self.writevar = tkinter.StringVar()

        self.mainframe = ttk.Frame(self.root, padding="3 3 12 12")
        self.mainframe.grid(column=0, row=0, sticky='nsew')
        self.mainframe.columnconfigure(0, weight=1)
        self.mainframe.rowconfigure(0, weight=1)

        self.label = ttk.Label(self.mainframe, textvariable=self.labelvar, font=('bold'))
        self.vote = ttk.Button(self.mainframe, text='Vote', command=self.quit)
        self.don_box = ttk.Radiobutton(self.mainframe, text='Donald Trump', variable=self.votevar, value='trump', command=self.write)
        self.stein_box = ttk.Radiobutton(self.mainframe, text='Jill Stein', variable=self.votevar, value='stein', command=self.write)
        self.write_box = ttk.Radiobutton(self.mainframe, text='Write in: ', variable=self.votevar, value='write', command=self.write)
        self.write_in = ttk.Entry(self.mainframe, textvariable= self.writevar, width=20, state='disabled')

        self.label.grid(column=2, row=0)
        self.vote.grid(column=4, row=5, sticky='e')
        self.don_box.grid(column=2, row=1, sticky='w')
        self.stein_box.grid(column=2, row=3, sticky='w')
        self.write_box.grid(column=2, row=4, sticky='w')
        self.write_in.grid(column=3, row=4, stick='w')

        self.labelvar.set('Presidential Nominees')

        for child in self.mainframe.winfo_children():
            child.grid_configure(padx=5, pady=5)

    def quit(self):
        self.root.destroy()

    def write(self):
        if self.votevar.get() == 'write':
            self.write_in['state'] = 'normal'
        else:
            self.write_in['state'] = 'disabled'
            self.writevar.set('')

    def run(self):
        self.root.mainloop()

MyApp().run()

答案 1 :(得分:1)

您收到NoneType个异常,因为write_in对象实际上是None

问题是您将write_in声明为:

write_in = ttk.Entry(...).grid(column=3, row=4, sticky=W)

grid方法会返回None结果。

grid的调用必须与小部件声明分开:

write_in = ttk.Entry(...)
write_in.grid(column=3, row=4, sticky=W)

关于改变小部件状态的方式,我不确定它应该有效。

尝试使用config(或configure)窗口小部件方法,并将state关键字设置为NORMAL

write_in.config(state=NORMAL)