5 class RadioSelect(Pmw.MegaWidget):
6 # A collection of several buttons. In single mode, only one
7 # button may be selected. In multiple mode, any number of buttons
10 def __init__(self, parent = None, **kw):
12 # Define the megawidget options.
15 ('buttontype', 'button', INITOPT),
16 ('command', None, None),
17 ('labelmargin', 0, INITOPT),
18 ('labelpos', None, INITOPT),
19 ('orient', 'horizontal', INITOPT),
22 ('selectmode', 'single', INITOPT),
24 self.defineoptions(kw, optiondefs, dynamicGroups = ('Button',))
26 # Initialise the base class (after defining the options).
27 Pmw.MegaWidget.__init__(self, parent)
29 # Create the components.
30 interior = self.interior()
31 if self['labelpos'] is None:
32 self._radioSelectFrame = self._hull
34 self._radioSelectFrame = self.createcomponent('frame',
36 Tkinter.Frame, (interior,))
37 self._radioSelectFrame.grid(column=2, row=2, sticky='nsew')
38 interior.grid_columnconfigure(2, weight=1)
39 interior.grid_rowconfigure(2, weight=1)
41 self.createlabel(interior)
43 # Initialise instance variables.
45 if self['selectmode'] == 'single':
46 self._singleSelect = 1
47 elif self['selectmode'] == 'multiple':
48 self._singleSelect = 0
50 raise ValueError, 'bad selectmode option "' + \
51 self['selectmode'] + '": should be single or multiple'
53 if self['buttontype'] == 'button':
54 self.buttonClass = Tkinter.Button
55 elif self['buttontype'] == 'radiobutton':
56 self._singleSelect = 1
57 self.var = Tkinter.StringVar()
58 self.buttonClass = Tkinter.Radiobutton
59 elif self['buttontype'] == 'checkbutton':
60 self._singleSelect = 0
61 self.buttonClass = Tkinter.Checkbutton
63 raise ValueError, 'bad buttontype option "' + \
64 self['buttontype'] + \
65 '": should be button, radiobutton or checkbutton'
67 if self._singleSelect:
72 if self['orient'] not in ('horizontal', 'vertical'):
73 raise ValueError, 'bad orient option ' + repr(self['orient']) + \
74 ': must be either \'horizontal\' or \'vertical\''
76 # Check keywords and initialise options.
77 self.initialiseoptions()
79 def getcurselection(self):
80 if self._singleSelect:
83 return tuple(self.selection)
86 return self.getcurselection()
88 def setvalue(self, textOrList):
89 if self._singleSelect:
90 self.__setSingleValue(textOrList)
93 oldselection = self.selection
94 self.selection = textOrList
95 for button in self._buttonList:
96 if button in oldselection:
97 if button not in self.selection:
98 # button is currently selected but should not be
99 widget = self.component(button)
100 if self['buttontype'] == 'checkbutton':
103 widget.configure(relief='raised')
105 if button in self.selection:
106 # button is not currently selected but should be
107 widget = self.component(button)
108 if self['buttontype'] == 'checkbutton':
111 widget.configure(relief='sunken')
113 def numbuttons(self):
114 return len(self._buttonList)
116 def index(self, index):
117 # Return the integer index of the button with the given index.
119 listLength = len(self._buttonList)
120 if type(index) == types.IntType:
121 if index < listLength:
124 raise ValueError, 'index "%s" is out of range' % index
125 elif index is Pmw.END:
127 return listLength - 1
129 raise ValueError, 'RadioSelect has no buttons'
131 for count in range(listLength):
132 name = self._buttonList[count]
135 validValues = 'a name, a number or Pmw.END'
137 'bad index "%s": must be %s' % (index, validValues)
139 def button(self, buttonIndex):
140 name = self._buttonList[self.index(buttonIndex)]
141 return self.component(name)
143 def add(self, componentName, **kw):
144 if componentName in self._buttonList:
145 raise ValueError, 'button "%s" already exists' % componentName
148 lambda self=self, name=componentName: self.invoke(name)
149 if not kw.has_key('text'):
150 kw['text'] = componentName
152 if self['buttontype'] == 'radiobutton':
153 if not kw.has_key('anchor'):
155 if not kw.has_key('variable'):
156 kw['variable'] = self.var
157 if not kw.has_key('value'):
158 kw['value'] = kw['text']
159 elif self['buttontype'] == 'checkbutton':
160 if not kw.has_key('anchor'):
163 button = apply(self.createcomponent, (componentName,
165 self.buttonClass, (self._radioSelectFrame,)), kw)
167 if self['orient'] == 'horizontal':
168 self._radioSelectFrame.grid_rowconfigure(0, weight=1)
169 col = len(self._buttonList)
170 button.grid(column=col, row=0, padx = self['padx'],
171 pady = self['pady'], sticky='nsew')
172 self._radioSelectFrame.grid_columnconfigure(col, weight=1)
174 self._radioSelectFrame.grid_columnconfigure(0, weight=1)
175 row = len(self._buttonList)
176 button.grid(column=0, row=row, padx = self['padx'],
177 pady = self['pady'], sticky='ew')
178 self._radioSelectFrame.grid_rowconfigure(row, weight=1)
180 self._buttonList.append(componentName)
184 for name in self._buttonList:
185 self.destroycomponent(name)
186 self._buttonList = []
187 if self._singleSelect:
188 self.selection = None
192 def __setSingleValue(self, value):
193 self.selection = value
194 if self['buttontype'] == 'radiobutton':
195 widget = self.component(value)
198 for button in self._buttonList:
199 widget = self.component(button)
201 widget.configure(relief='sunken')
203 widget.configure(relief='raised')
205 def invoke(self, index):
206 index = self.index(index)
207 name = self._buttonList[index]
209 if self._singleSelect:
210 self.__setSingleValue(name)
211 command = self['command']
212 if callable(command):
215 # Multiple selections
216 widget = self.component(name)
217 if name in self.selection:
218 if self['buttontype'] == 'checkbutton':
221 widget.configure(relief='raised')
222 self.selection.remove(name)
225 if self['buttontype'] == 'checkbutton':
228 widget.configure(relief='sunken')
229 self.selection.append(name)
232 command = self['command']
233 if callable(command):
234 return command(name, state)