From 459ff956c2554ab432e9790e3fa2761e18e7904a Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 15 Sep 2014 18:05:04 +0000 Subject: [PATCH] [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. Fixes Issue 235. --- .../cython/cantera/mixmaster/ControlPanel.py | 55 +++++++++---------- .../cython/cantera/mixmaster/MechManager.py | 4 +- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/interfaces/cython/cantera/mixmaster/ControlPanel.py b/interfaces/cython/cantera/mixmaster/ControlPanel.py index 9eca455ac..1f167e3c6 100644 --- a/interfaces/cython/cantera/mixmaster/ControlPanel.py +++ b/interfaces/cython/cantera/mixmaster/ControlPanel.py @@ -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): diff --git a/interfaces/cython/cantera/mixmaster/MechManager.py b/interfaces/cython/cantera/mixmaster/MechManager.py index a1d2e6e91..75f0f166f 100644 --- a/interfaces/cython/cantera/mixmaster/MechManager.py +++ b/interfaces/cython/cantera/mixmaster/MechManager.py @@ -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)