编辑现在已经转移到Python 3.4.3 tkinter - Program freezes on declaration of IntVar or any other tkinter data type,因为这是问题的根源,现在已经解决了。基本上,从来没有说过任何一个" master"在Python 3.x中使用tkinter,它会导致一个无限循环:(。我的完整代码现已被删除,因为它是我的课程作业,并且不希望有人对它进行修改:D EDIT
我对tkinter相对较新,无法查看我出错的地方。我尝试使用StringVar()和常规字符串来获取多个输入字段,以便在启用Checkbutton时禁用。这是问题所在的框架:
class CActivity(tk.Frame):
def Clear(self):
pass # To be completed
def Today(self):
if self.todayVar == "ON":
self.day.configure(state="disabled")
self.month.configure(state="disabled")
self.year.configure(state="disabled")
else:
self.day.configure(state="normal")
self.month.configure(state="normal")
self.year.configure(state="normal")
def createWidgets(self):
self.title = tk.Label(self)
self.title["text"] = "Add an Activity"
self.title["font"] = ("Times New Roman",30)
self.title["fg"] = "purple"
self.title.grid(row=0,column=0,sticky="W",padx=5,pady=5)
self.todayVar = ""
tk.Label(self,text="Activity Name:",font=("Times New Roman",15)).grid(row=1,column=0,sticky="W",padx=5,pady=5)
name = tk.Entry(self).grid(row=1,column=1,columnspan=3,sticky="E",padx=5,pady=5)
tk.Label(self,text="Priority:",font=("Times New Roman",15)).grid(row=2,column=0,sticky="W",padx=5,pady=5)
priority = tk.Checkbutton(self).grid(row=2,column=1,sticky="W",padx=0,pady=5)
tk.Label(self,text="Today?",font=("Times New Roman",15)).grid(row=3,column=0,sticky="W",padx=5,pady=5)
today = tk.Checkbutton(self,onvalue="ON",offvalue="OFF",variable=self.todayVar,command=self.Today).grid(row=3,column=1,sticky="W",padx=0,pady=5) #problem possibly on this line
tk.Label(self,text="Date (DD/MM/YYYY):",font=("Times New Roman",15)).grid(row=4,column=0,sticky="W",padx=5,pady=5)
day = tk.Entry(self,width=2).grid(row=4,column=1,sticky="W",padx=2,pady=5)
month = tk.Entry(self,width=2).grid(row=4,column=2,sticky="W",padx=2,pady=5)
year = tk.Entry(self,width=4).grid(row=4,column=3,sticky="W",padx=2,pady=5)
self.clear = tk.Button(self, command=self.Clear)
self.clear["text"] = "Clear"
self.clear["font"] = ("Times New Roman",15)
self.clear["fg"] = "red"
self.clear.grid(row=7,column=4,sticky="WE",padx=5,pady=5)
self.back = tk.Button(self)
self.back["text"] = "Back"
self.back["font"] = ("Times New Roman",15)
self.back["fg"] = "red"
self.back["command"] = self.parent.Menu
self.back.grid(row=8,column=4,sticky="WE",padx=5,pady=5)
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.pack()
self.parent = parent
self.createWidgets()
这里是使用StringVar()而不是标准的Python字符串:
class CActivity(tk.Frame):
def Clear(self):
pass # To be completed
def Today(self):
if self.todayVar.get() == "ON":
self.day.configure(state="disabled")
self.month.configure(state="disabled")
self.year.configure(state="disabled")
else:
self.day.configure(state="normal")
self.month.configure(state="normal")
self.year.configure(state="normal")
def createWidgets(self):
self.title = tk.Label(self)
self.title["text"] = "Add an Activity"
self.title["font"] = ("Times New Roman",30)
self.title["fg"] = "purple"
self.title.grid(row=0,column=0,sticky="W",padx=5,pady=5)
self.todayVar = tk.StringVar()
tk.Label(self,text="Activity Name:",font=("Times New Roman",15)).grid(row=1,column=0,sticky="W",padx=5,pady=5)
name = tk.Entry(self).grid(row=1,column=1,columnspan=3,sticky="E",padx=5,pady=5)
tk.Label(self,text="Priority:",font=("Times New Roman",15)).grid(row=2,column=0,sticky="W",padx=5,pady=5)
priority = tk.Checkbutton(self).grid(row=2,column=1,sticky="W",padx=0,pady=5)
tk.Label(self,text="Today?",font=("Times New Roman",15)).grid(row=3,column=0,sticky="W",padx=5,pady=5)
today = tk.Checkbutton(self,onvalue="ON",offvalue="OFF",variable=self.todayVar,command=self.Today).grid(row=3,column=1,sticky="W",padx=0,pady=5)
tk.Label(self,text="Date (DD/MM/YYYY):",font=("Times New Roman",15)).grid(row=4,column=0,sticky="W",padx=5,pady=5)
day = tk.Entry(self,width=2).grid(row=4,column=1,sticky="W",padx=2,pady=5)
month = tk.Entry(self,width=2).grid(row=4,column=2,sticky="W",padx=2,pady=5)
year = tk.Entry(self,width=4).grid(row=4,column=3,sticky="W",padx=2,pady=5)
self.clear = tk.Button(self, command=self.Clear)
self.clear["text"] = "Clear"
self.clear["font"] = ("Times New Roman",15)
self.clear["fg"] = "red"
self.clear.grid(row=7,column=4,sticky="WE",padx=5,pady=5)
self.back = tk.Button(self)
self.back["text"] = "Back"
self.back["font"] = ("Times New Roman",15)
self.back["fg"] = "red"
self.back["command"] = self.parent.Menu
self.back.grid(row=8,column=4,sticky="WE",padx=5,pady=5)
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.pack()
self.parent = parent
self.createWidgets()
在使用标准字符串的情况下,程序运行正常,直到您单击Checkbutton,此时Checkbutton变为灰色,然后程序停止响应。在使用StringVar()的情况下,由于在窗口初始化期间初始化该帧,所以tk窗口根本不加载。感谢您的帮助,如果您想要完整的代码来帮助我找到问题,请告诉我们。
答案 0 :(得分:0)
以下是正确运行的代码的简化版本:
#!/usr/bin/env python
''' Toggle disable / normal of Tkinter widgets
Written by PM 2Ring & R. Murray 2015.11.15
See http://stackoverflow.com/q/33711472/4014959
'''
#Python 3 / Python 2 Tkinter import
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class CActivity(tk.Frame):
def today_cb(self):
if self.todayVar.get():
state = "disabled"
else:
state = "normal"
#print(state)
self.day.configure(state=state)
self.month.configure(state=state)
self.year.configure(state=state)
def create_widgets(self):
title_text = ("Click the 'Today' Checkbutton to\n"
"disable / enable date Entry widgets")
title = tk.Label(self, text=title_text)
title.grid(row=0, column=0, sticky="W", padx=5, pady=5)
self.todayVar = tk.IntVar()
tk.Label(self,text="Today").grid(row=1, column=1,
sticky="W", padx=0, pady=5)
today = tk.Checkbutton(self, variable=self.todayVar,
command=self.today_cb)
today.grid(row=2, column=1, sticky="W", padx=0, pady=5)
#Date Entry widgets
tk.Label(self,text="Day").grid(row=3, column=1,
sticky="W", padx=2, pady=5)
self.day = tk.Entry(self, width=2)
self.day.grid(row=4, column=1, sticky="W", padx=2, pady=5)
tk.Label(self,text="Month").grid(row=3, column=2,
sticky="W", padx=2,pady=5)
self.month = tk.Entry(self, width=2)
self.month.grid(row=4, column=2, sticky="W", padx=2, pady=5)
tk.Label(self,text="Year").grid(row=3, column=3,
sticky="W", padx=2, pady=5)
self.year = tk.Entry(self, width=4)
self.year.grid(row=4, column=3, sticky="W", padx=2, pady=5)
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.pack()
self.parent = parent
self.create_widgets()
if __name__ == '__main__':
master = tk.Tk()
master.title("Disable widgets demo")
frame = CActivity(master)
master.mainloop()
您的代码存在一些问题。
您的createWidgets
方法会将日期Entry
小部件保存到本地变量中,例如day
,但它们必须属于实例属性,例如{{1因此可以通过self.day
的回调方法访问它们。
另一个问题是你在与widget构造函数相同的行上调用Checkbutton
方法。该方法返回.grid
,所以正在执行
None
将day = tk.Entry(self,width=2).grid(row=4,column=1)
设置为无。
如果您不需要保存对窗口小部件的引用,可以在与构造函数相同的行上使用day
(或.grid
),但是当您使用它时它将无效做需要该引用。 :)
我稍微简化了.pack
的回调方法,以减少代码重复。我摆脱了Checkbutton
构造函数中的onvalue="ON",offvalue="OFF"
,因为默认的0和1足以完成此任务,恕我直言,(但如果你愿意,可以随意改回:)),因为我们使用的是数字状态,所以我使用Checkbutton
而不是字符串或StringVar。
我还要更改方法的名称以符合PEP 8约定。
您仍然对代码中的局部变量与实例变量存在一些混淆。 IntVar
与day
不同,所以你需要解决这个问题,例如,
self.day
需要
day = tk.Entry(self,width=2)
self.day.grid(row=4,column=1,sticky="W",padx=2,pady=5)
另外,请记住Bryan Oakley所说的关于小部件self.day = tk.Entry(self,width=2)
self.day.grid(row=4,column=1,sticky="W",padx=2,pady=5)
和variable
属性需要引用Tkinter textvariable
,StringVar
等实例的内容。
答案 1 :(得分:0)
variable
和textvariable
属性需要引用Tkinter StringVar
,IntVar
,DoubleVar
或BooleanVar
的实例。你不能使用普通变量。
其次,您必须使用这些变量的get
方法,才能在if
语句中对它们进行比较之前检索这些值。
self.todayVar = StringVar()
...
today = tk.Checkbutton(..., variable=self.todayVar, ...)
...
if self.todayVar.get() == "ON":