[MixMaster] Fix crash when using Tcl 8.6

Tcl/Tk changed some operations which previously resulted in undefined behavior
into errors, including one case that occurred when updating the "Mixtures" menu
in MixMaster.

MixMaster now modifies the existing Menu when adding an item, rather than
completely regenerating it, which avoids this problem.

Cherry-pick of trunk r3162.
This commit is contained in:
Ray Speth 2014-09-15 18:06:18 +00:00
parent 3eb6cb0f9d
commit f9fa476c39
2 changed files with 27 additions and 32 deletions

View file

@ -106,40 +106,35 @@ def make_menu(name, menubar, lst):
button=Menubutton(menubar, text=name, width=nc+4, padx=3,pady=1)
button.pack(side=LEFT)
menu = Menu(button,tearoff=FALSE)
m = menu
i = 0
for entry in lst:
i += 1
if entry == 'separator':
menu.add_separator({})
elif isinstance(entry, list):
for num in entry:
menu.entryconfig(num,state=DISABLED)
elif not isinstance(entry[1], list):
if i == 20:
i = 0
submenu = Menu(button,tearoff=FALSE)
m.add_cascade(label='More...',
menu=submenu)
m = submenu
if len(entry) == 2 or entry[2] == 'command':
m.add_command(label=entry[0],
command=entry[1])
elif entry[2] == 'check':
entry[3].set(0)
if len(entry) >= 5: val = entry[4]
else: val = 1
m.add_checkbutton(label=entry[0],
command=entry[1],
variable = entry[3],
onvalue=val)
else:
submenu=make_menu(entry[0], menu, entry[1])
m.add_cascade(label=entry[0],
menu=submenu)
add_menu_item(menu, entry)
button['menu']=menu
return button
def add_menu_item(menu, entry):
if entry == 'separator':
menu.add_separator({})
elif isinstance(entry, list):
for num in entry:
menu.entryconfig(num,state=DISABLED)
elif not isinstance(entry[1], list):
if len(entry) == 2 or entry[2] == 'command':
menu.add_command(label=entry[0],
command=entry[1])
elif entry[2] == 'check':
entry[3].set(0)
if len(entry) >= 5: val = entry[4]
else: val = 1
menu.add_checkbutton(label=entry[0],
command=entry[1],
variable = entry[3],
onvalue=val)
else:
submenu=make_menu(entry[0], menu, entry[1])
menu.add_cascade(label=entry[0],
menu=submenu)
def menuitem_state(button, *statelist):
for menu in button.children.keys():
if isinstance(button.children[menu], Menu):

View file

@ -7,7 +7,7 @@ else:
from Tkinter import *
from .ControlPanel import ControlWindow
from .ControlPanel import make_menu, menuitem_state
from .ControlPanel import make_menu, menuitem_state, add_menu_item
#from Cantera.Examples.Tk import _mechdir
import os
@ -52,9 +52,9 @@ class MechManager(Frame):
self.mechanisms.append((name, mech))
il = len(self.mechanisms)
self.mlist[-1] = (name, self.setMechanism, 'check', self.mechindx, il)
add_menu_item(list(self.mechmenu.children.values())[0], self.mlist[-1])
self.mlist.append([])
self.mechmenu = make_menu('Mixtures', self, self.mlist)
self.mechindx.set(il)
self.mechmenu.grid(row=0,column=0,sticky=W)