as a side project to my usual work, I was asked to create a form to collect information. Now the script is in shape and basically does all that I needed, but I would like to add an extra feature. Basically, I have some fields that are made of 3 widgets: a Label with some question, a drop-down menu with a "Yes"/"No" list to select and an optional text widget where the User could provide extra information (usually if the selection from the drop-down was "Yes") Currently the text widget is always active (i.e. the User can write everything that I wants) and it is just during a post-processing phase (made by the script) that I collect its content depending on the value of the drop-down selection.
This is basically fine, but I would like to have it more visually appealing by having the text widget enabled or not depending by the value of the drop-down. Basically, my idea is to have the text widget disabled by default, and if the User select "Yes" from the drop list, then the widget become editable.
I tried to do it like this:
#! /bin/env python
from Tkinter import *
#
my_change = "No"
stateOpts = ['normal','disabled']
win_width = 610
win_height =866
# My frame for form
class simpleform_ap(Tk):
#my_sel = ""
global my_change
# constructor
def __init__(self,parent):
Tk.__init__(self,parent)
self.parent = parent
self.initialize()
#
def initialize(self):
#
# Default Window Size
self.geometry(str(win_width) + "x" + str(win_height))
#
self.grid_columnconfigure(0,weight=4)
self.grid_rowconfigure(0,weight=1)
#
# Create a Canvas
self.canvas=Canvas(self.parent)
self.canvas.grid(row=0,column=0,sticky='nsew')
#
# Add a Frame inside my canvas
self.frame1 = Frame(self.canvas)
#
# Create canvas window
self.canvas.create_window(0,0,window=self.frame1,anchor='nw')
#
curr_row = 1
text_height = 8
text_width = 5*text_height
# Label
self.labelVariableChanges = StringVar() # Label variable
labelChanges=Label(self.frame1,textvariable=self.labelVariableChanges,
anchor="nw",
fg="Black")
labelChanges.grid(column=0,row=curr_row,columnspan=1,sticky='EW')
self.labelVariableChanges.set("Do your selection: ")
# Selection
optionList = ["Yes","No"]
self.dropVarChanges=StringVar()
self.dropVarChanges.set("Select")
self.dropMenuChanges = OptionMenu(self.frame1 ,self.dropVarChanges,
*optionList, command=self.get_Change_selection)
self.dropMenuChanges.grid(column=2,row=curr_row)
curr_row = curr_row+1
# Text
self.textStateChanges = stateOpts[1]
self.TextVarChanges=StringVar()
#
self.textChanges=Text(self.frame1,state=self.textStateChanges,
height = text_height, width = text_width,
fg="black",bg="white") # ,textvariable=self.myTextVar)
#
self.textChanges.grid(column=1, row=curr_row+3, columnspan=2, sticky='EW')
self.textChanges.insert('1.0',"If Yes, add changes here!")
#
#
# Update Geometry
self.update()
self.geometry(self.geometry() )
self.frame1.update_idletasks()
self.canvas.config(scrollregion=(0,0,self.frame1.winfo_width(),self.frame1.winfo_height()))
#
# end initialize()
def get_Change_selection(self,value):
global my_change
#
my_change = value
if value == 'Yes':
#
self.textStateChanges = stateOpts[0]
#
self.dropVarChanges.set(value)
return
def release_block(argv):
# Create Form
form = simpleform_ap(None)
form.title('Release Information')
#
form.mainloop()
print "Done"
#
if __name__ == "__main__":
release_block(sys.argv)
but I failed (basically I am a n00b with TKinter).
I guess the problem is in the mainloop and in the function to retrieve the selection, but I cannot figure out how to solve this.
Does anybody have an idea on how to fix this?
Thanks in advance to everybody that is willing to give me some hints.
You can enable/disable the text widget by calling self.textChanges.config()
and passing it the state. This amounts to modifying your get_Change_selection
to read:
def get_Change_selection(self,value):
global my_change
my_change = value
if value == 'Yes':
self.textChanges.config(state=stateOpts[0])
else:
self.textChanges.config(state=stateOpts[1])
self.dropVarChanges.set(value)
return
If you'd like to disable the field by default, add a call to config in the constructor to disable it. After making these changes, your code would look like:
from Tkinter import *
#
my_change = "No"
stateOpts = ['normal', 'disabled']
win_width = 610
win_height =866
# My frame for form
class simpleform_ap(Tk):
#my_sel = ""
global my_change
# constructor
def __init__(self,parent):
Tk.__init__(self,parent)
self.parent = parent
self.initialize()
#
def initialize(self):
#
# Default Window Size
self.geometry(str(win_width) + "x" + str(win_height))
#
self.grid_columnconfigure(0,weight=4)
self.grid_rowconfigure(0,weight=1)
#
# Create a Canvas
self.canvas=Canvas(self.parent)
self.canvas.grid(row=0,column=0,sticky='nsew')
#
# Add a Frame inside my canvas
self.frame1 = Frame(self.canvas)
#
# Create canvas window
self.canvas.create_window(0,0,window=self.frame1,anchor='nw')
#
curr_row = 1
text_height = 8
text_width = 5*text_height
# Label
self.labelVariableChanges = StringVar() # Label variable
labelChanges=Label(self.frame1,textvariable=self.labelVariableChanges,
anchor="nw",
fg="Black")
labelChanges.grid(column=0,row=curr_row,columnspan=1,sticky='EW')
self.labelVariableChanges.set("Do your selection: ")
# Selection
optionList = ["Yes","No"]
self.dropVarChanges=StringVar()
self.dropVarChanges.set("Select")
self.dropMenuChanges = OptionMenu(self.frame1 ,self.dropVarChanges,
*optionList, command=self.get_Change_selection)
self.dropMenuChanges.grid(column=2,row=curr_row)
curr_row = curr_row+1
# Text
self.textStateChanges = stateOpts[1]
self.TextVarChanges=StringVar()
#
self.textChanges=Text(self.frame1,state=self.textStateChanges,
height = text_height, width = text_width,
fg="black",bg="white") # ,textvariable=self.myTextVar)
#
self.textChanges.grid(column=1, row=curr_row+3, columnspan=2, sticky='EW')
self.textChanges.insert('1.0',"If Yes, add changes here!")
self.textChanges.config(state=stateOpts[1])
#
#
# Update Geometry
self.update()
self.geometry(self.geometry() )
self.frame1.update_idletasks()
self.canvas.config(scrollregion=(0,0,self.frame1.winfo_width(),self.frame1.winfo_height()))
#
# end initialize()
def get_Change_selection(self,value):
global my_change
my_change = value
if value == 'Yes':
self.textChanges.config(state=stateOpts[0])
else:
self.textChanges.config(state=stateOpts[1])
self.dropVarChanges.set(value)
return
def release_block(argv):
# Create Form
form = simpleform_ap(None)
form.title('Release Information')
#
form.mainloop()
print("Done")
#
if __name__ == "__main__":
release_block(sys.argv)