How to link 3 Tkinter OptionMenu lists?

Stewart Midwinter stewart at midtoad.homelinux.org
Wed Feb 25 07:57:30 CET 2004


I would like to link the contents of three OptionMenu lists. When I select an
item from the first list (call it continents), the contents of the 2nd list
(call it countries) would update. And in turn the contents of the 3rd list (call
it states would be updated by a change in the 2nd list.  If anyone can share a
recipe or some ideas, I'd be grateful!

Here's some sample code that displays three OptionMenus, but doesn't update the
list contents :-(

---
#file selectSystem.py
title = 'linked OptionMenus'

# Import Pmw from this directory tree.
import sys
sys.path[:0] = ['../../..']

import Tkinter
import Pmw, re

global continentList, countryList, stateList

continentList = ['N.America','C. America', 'S. America']
countryList   = [['Canada','USA','Mexico'],
		['Guatemala','Nicaragua','Panama'],
		['Venezuela','Colombia','Ecuador']]
stateList     = [[['BC','Alberta','Saskatchewan','others'],
		['California','Oregon','Washington','others'],
		['Michoacan','Oaxaca','Monterrey','others']],
		[['Guatemala states'],['Nicaragua states'],['Panama states']],
		[['Venezuela states'],['Colombia states'],['Ecuador states']]]

# default selection
continentItem = continentList[0]
countryItem   = countryList[0][0]
stateItem     = stateList[0][0][0]

class selectSystem:
    def __init__(self, parent):
	# Create and pack the OptionMenu megawidgets.
	# The first one has a textvariable.
	self.var1 = Tkinter.StringVar()
	self.var2 = Tkinter.StringVar()
	self.var3 = Tkinter.StringVar()
	self.var1.set(continentItem)	# N. America
	self.var2.set(countryItem)	# Canada
	self.var3.set(stateItem)	# B.C.

	self.method1_menu = Pmw.OptionMenu(parent,
		labelpos = 'w',
		label_text = 'Select Continent:',
		menubutton_textvariable = self.var1,
		items = continentList,
		menubutton_width = 20,
		menubutton_direction = 'flush',
		command = self._getSelection
	)
	self.method1_menu.pack(anchor = 'w', padx = 10, pady = 10)

	self.method2_menu = Pmw.OptionMenu (parent,
		labelpos = 'w',
		label_text = 'Select country:',
		menubutton_textvariable = self.var2,
		items = countryList[0],
		menubutton_width = 20,
		menubutton_direction = 'flush',
		command = self._getSelection
	)
	self.method2_menu.pack(anchor = 'w', padx = 10, pady = 10)

	self.method3_menu = Pmw.OptionMenu (parent,
		labelpos = 'w',
		label_text = 'Select state:',
		menubutton_textvariable = self.var3,
		items = stateList[0][0],
		menubutton_width = 20,
		menubutton_direction = 'flush' ,
		command = self._getSelection
	)
	self.method3_menu.pack(anchor = 'w', padx = 10, pady = 10)

	menus = (self.method1_menu, self.method2_menu, self.method3_menu)
	Pmw.alignlabels(menus)

	# Create the dialog.
	self.dialog = Pmw.Dialog(parent,
	    buttons = ('OK', 'Apply', 'Cancel', 'Help'),
	    defaultbutton = 'OK',
	    title = 'Select State',
	    command = self.execute)
	self.dialog.withdraw()

	# Add some contents to the dialog.
	w = Tkinter.Label(self.dialog.interior(),
	    text = 'Pmw Dialog\n(put your widgets here)',
	    background = 'black',
	    foreground = 'white',
	    pady = 20)
	w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)

    def showAppModal(self):
        self.dialog.activate(geometry = 'centerscreenalways')

    def execute(self, result):
	print 'You clicked on', result
	if result not in ('Apply', 'Help'):
	    self.dialog.deactivate(result)

    def _getSelection(self, choice):
	# Can use 'self.var.get()' instead of 'getcurselection()'.
	print 'You have chosen %s : %s : %s' % \
            (self.var1.get(), 
	     self.var2.get(), 
	     self.var3.get() )
	print choice  # debug
	i2 = indexContinent(self.var1.get())
	self.var2.set(countryList[i2][0])
	countryItem = countryList[i2]
	#print pipelineItems  # debug
	self.method2_menu.config(items = countryList)
	#s3 = systemElements.indexpipe(s2,test2)

    def __call__(self):
	self.dialog.show()

def indexContinent(name):
	found = 'false'
	for i in range(len(continentList)):
		check = continentList[i]
		# print 'checking %s in %s' % (name, check)  # debug
		if re.search(name,check):
			found = 'true'
			break
	print found
	if (found=='true'):
		#print 'index of %s is %s' % (name,i)  # debug
		return i
	else:
		return -1

def indexCountry(continentindex, name):
	found = 'false'
	for i in range(len(countryList[continentindex])):
		check = countryList[continentindex][i]
		# print 'checking %s in %s' % (name, check)  # debug
		if re.search(name,check):
			found = 'true'
			break
	print found
	if (found=='true'):
		#print 'index of %s is %s' % (name,i)  # debug
		return i
	else:
		return -1


#############################

# Create selectSystem in root window for testing.
if __name__ == '__main__':
    root = Tkinter.Tk()
    Pmw.initialise(root)
    root.title(title)

    OKButton = Tkinter.Button(root, text = 'OK', command = root.destroy)
    OKButton.pack(side = 'bottom')

    widget = selectSystem(root)
    root.mainloop()
-----



-- 
Stewart Midwinter
running on Mandrake Linux 9.2
PGP public key at: http://www.keyserver.net
e-mail: Stewart 'at' Midwinter.ca, stewart 'at' midtoad.homelinux.org
web: http://www.midwinter.ca, http://midtoad.homelinux.org
voice: +1.403.714.4329

Umwelt schuetzen, Rad benuetzen!






More information about the Python-list mailing list