S
Stewart Midwinter
I have a Tkinter app running on cygwin. It includes a Test menu item
that does nothing more than fetch a directory listing and display it
in a Toplevel window (I'd use a tkMessageBox showinfo widget, but for
some reason the text is invisible on cygwin).
After I close the Toplevel widget, all of the menus in my app behave
as though they have no contents to them, i..e I can press on the File
menu button, and see it depress, but the Exit submenu does not appear
(and neither do any of the other menus' submenus). However, a Quit
button in my status bar does respond, so the problem lies with the
menu.
Below are two apps that illustrate the problem. It's obvious that the
problem is with Pmw, and in particular with the menubar widget. The
first test app uses Pmw, and displays the problem behaviour. The
second test app uses basic Tk menus, and does not have a problem.
Any clues?
---
#test_subprocess3.py
from Tkinter import *
import os, sys
import subprocess
programHome = '/cygdrive/c/programs'
sys.path[:0] = [programHome]
try:
import Pmw
except ImportError:
print 'I need to have Pmw widget set installed in c:\\Programs\\Pmw'
sys.exit("missing Pmw")
class PumpAdmin(Pmw.MegaWidget):
def __init__(self, parent): #master=None):
Pmw.MegaWidget.__init__(self, parent)
#Frame.__init__(self, master, relief=SUNKEN, bd=2)
self.parent = parent
def drawGui(self):
'''draw the application'''
# Create the Balloon.
self.balloon = Pmw.Balloon(self.parent)
#---------- Menu bar ---------------
if 1:
menuBar=Pmw.MenuBar(self.parent, hull_relief='raised',
hull_borderwidth=1)
menuBar.pack(fill='x')
self.menuBar = menuBar
menuBar.addmenu('File', 'Close this window or exit')
menuBar.addmenuitem('File', 'command', 'Exit the
application', command=root.destroy, label='Exit')
menuBar.addmenu('Test', 'Test new features')
menuBar.addmenuitem('Test', 'command', 'Directory
listing', command=self.dir_list, label='Directory List')
# ------- Paned widget (central part of main window) -------
if 1:
panedWidget = Pmw.PanedWidget(self.parent,
orient = 'vertical', hull_height = 250, hull_width = 500)
self.panedWidget = panedWidget
self.panedWidget.add('results', min = 0.05)
self.panedWidget.pack(side='left', fill = 'both', expand = 1)
self.results =
Pmw.ScrolledText(self.panedWidget.pane('results'), text_wrap = 'none')
self.results.pack(fill = 'both', expand = 1)
# ----------------------- Status Bar --------------------------
if 1:
self.panedWidget.add('status', min = 0.05)
frmS = Frame(self.panedWidget.pane('status'))
self.frmS = frmS
frmS.pack(fill='x', expand=1)
labSpaceL = Label(frmS, text = ' ')
labSpaceR = Label(frmS, text = ' ')
labSystem = Button(frmS, text = 'Quit', command=root.destroy)
self.labSystem = labSystem
labSpaceL.pack(side='left')
self.labSystem.pack(side='left', fill='both',expand=0)
labSpaceR.pack(side='right')
def dir_list(self):
'''provide a listing of files in a directory'''
curdir = os.getcwd()
try:
p = subprocess.Popen(['ls',' -l'], bufsize=2048,
shell=True, close_fds=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(child_stdin, dirlist, retcode) = (p.stdin, p.stdout, p.stderr)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", retcode
print 'error'
self.myshowerror("Error","Sorry, couldn't get a
directory listing")
else:
print 'no error'
#print dirlist
msgList = []
for dir in dirlist:
#print dir
msgList.append(dir)
msg = ''.join(msgList)
#print msg
print 'got to 1'
self.myshowinfo("Directory Listing for %s" % curdir, msg)
print 'got to 2'
#self.drawMenu()
except OSError,e:
print >>sys.stderr, "Execution failed:", e
def mymessage(self, title, msg, msgType='info'):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
top = Toplevel()
top.title(title)
t = Label(top, text='\n%s\n' % msgType.upper())
t.pack()
l = Label(top, text=msg)
l.pack()
b = Button(top,text="Ok", command=top.destroy)
b.pack()
def myshowinfo(self, title='', msg=''):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
self.mymessage(title, msg,'info')
root.focus_set()
root.update()
if __name__ == '__main__':
if 1:
root = Tk()
Pmw.initialise(root, size = 16, useTkOptionDb = 1)
root.geometry('500x400+100+100')
root.title("Test application")
app = PumpAdmin(root)
app.drawGui()
app.pack(fill = 'both', expand = 1)
root.deiconify()
root.update()
root.mainloop()
---
#test_subprocess2.py
from Tkinter import *
import os, sys
import subprocess
class AppUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master, relief=SUNKEN, bd=2)
def drawGui(self):
self.drawMenu()
self.drawCanvas()
def drawMenu(self):
self.menubar = Menu(self)
menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="File", menu=menu)
menu.add_command(label="Exit", command=root.destroy)
menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="Test", menu=menu)
menu.add_command(label="Dir list", command=self.dir_list)
try:
self.master.config(menu=self.menubar)
except AttributeError:
# master is a toplevel window (Python 1.4/Tkinter 1.63)
self.master.tk.call(master, "config", "-menu", self.menubar)
def drawCanvas(self):
self.canvas = Canvas(self, bg="white", width=400, height=400,
bd=0, highlightthickness=0)
self.canvas.pack()
def dir_list(self):
'''provide a listing of files in a directory'''
#need to know which system to draw from
curdir = os.getcwd()
try:
#dirlist = subprocess.Popen('ls -l', shell=False,
bufsize=2048, stdout=subprocess.PIPE).stdout
#dirlist,retcode = subprocess.Popen('ls -l',
stdout=subprocess.PIPE).communicate()
#retcode = subprocess.call('ls -l', shell=False)
p = subprocess.Popen(['ls',' -l'], bufsize=2048,
shell=True, close_fds=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(child_stdin, dirlist, retcode) = (p.stdin, p.stdout, p.stderr)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", retcode
print 'error'
self.myshowerror("Error","Sorry, couldn't get a
directory listing")
else:
print 'no error'
#print dirlist
msgList = []
for dir in dirlist:
#print dir
msgList.append(dir)
msg = ''.join(msgList)
#print msg
print 'got to 1'
self.myshowinfo("Directory Listing for %s" % curdir, msg)
print 'got to 2'
self.drawMenu()
except OSError,e:
print >>sys.stderr, "Execution failed:", e
def mymessage(self, title, msg, msgType='info'):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
top = Toplevel()
top.title(title)
t = Label(top, text='\n%s\n' % msgType.upper())
t.pack()
l = Label(top, text=msg)
l.pack()
b = Button(top,text="Ok", command=top.destroy)
b.pack()
def myshowinfo(self, title='', msg=''):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
self.mymessage(title, msg,'info')
root.focus_set()
root.update()
root = Tk()
app = AppUI(root)
app.drawGui()
app.pack()
root.mainloop()
thanks,
--
Stewart Midwinter
(e-mail address removed)
(e-mail address removed)
Skype, GoogleTalk, iChatAV, MSN, Yahoo: midtoad
AIM:midtoad1
that does nothing more than fetch a directory listing and display it
in a Toplevel window (I'd use a tkMessageBox showinfo widget, but for
some reason the text is invisible on cygwin).
After I close the Toplevel widget, all of the menus in my app behave
as though they have no contents to them, i..e I can press on the File
menu button, and see it depress, but the Exit submenu does not appear
(and neither do any of the other menus' submenus). However, a Quit
button in my status bar does respond, so the problem lies with the
menu.
Below are two apps that illustrate the problem. It's obvious that the
problem is with Pmw, and in particular with the menubar widget. The
first test app uses Pmw, and displays the problem behaviour. The
second test app uses basic Tk menus, and does not have a problem.
Any clues?
---
#test_subprocess3.py
from Tkinter import *
import os, sys
import subprocess
programHome = '/cygdrive/c/programs'
sys.path[:0] = [programHome]
try:
import Pmw
except ImportError:
print 'I need to have Pmw widget set installed in c:\\Programs\\Pmw'
sys.exit("missing Pmw")
class PumpAdmin(Pmw.MegaWidget):
def __init__(self, parent): #master=None):
Pmw.MegaWidget.__init__(self, parent)
#Frame.__init__(self, master, relief=SUNKEN, bd=2)
self.parent = parent
def drawGui(self):
'''draw the application'''
# Create the Balloon.
self.balloon = Pmw.Balloon(self.parent)
#---------- Menu bar ---------------
if 1:
menuBar=Pmw.MenuBar(self.parent, hull_relief='raised',
hull_borderwidth=1)
menuBar.pack(fill='x')
self.menuBar = menuBar
menuBar.addmenu('File', 'Close this window or exit')
menuBar.addmenuitem('File', 'command', 'Exit the
application', command=root.destroy, label='Exit')
menuBar.addmenu('Test', 'Test new features')
menuBar.addmenuitem('Test', 'command', 'Directory
listing', command=self.dir_list, label='Directory List')
# ------- Paned widget (central part of main window) -------
if 1:
panedWidget = Pmw.PanedWidget(self.parent,
orient = 'vertical', hull_height = 250, hull_width = 500)
self.panedWidget = panedWidget
self.panedWidget.add('results', min = 0.05)
self.panedWidget.pack(side='left', fill = 'both', expand = 1)
self.results =
Pmw.ScrolledText(self.panedWidget.pane('results'), text_wrap = 'none')
self.results.pack(fill = 'both', expand = 1)
# ----------------------- Status Bar --------------------------
if 1:
self.panedWidget.add('status', min = 0.05)
frmS = Frame(self.panedWidget.pane('status'))
self.frmS = frmS
frmS.pack(fill='x', expand=1)
labSpaceL = Label(frmS, text = ' ')
labSpaceR = Label(frmS, text = ' ')
labSystem = Button(frmS, text = 'Quit', command=root.destroy)
self.labSystem = labSystem
labSpaceL.pack(side='left')
self.labSystem.pack(side='left', fill='both',expand=0)
labSpaceR.pack(side='right')
def dir_list(self):
'''provide a listing of files in a directory'''
curdir = os.getcwd()
try:
p = subprocess.Popen(['ls',' -l'], bufsize=2048,
shell=True, close_fds=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(child_stdin, dirlist, retcode) = (p.stdin, p.stdout, p.stderr)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", retcode
print 'error'
self.myshowerror("Error","Sorry, couldn't get a
directory listing")
else:
print 'no error'
#print dirlist
msgList = []
for dir in dirlist:
#print dir
msgList.append(dir)
msg = ''.join(msgList)
#print msg
print 'got to 1'
self.myshowinfo("Directory Listing for %s" % curdir, msg)
print 'got to 2'
#self.drawMenu()
except OSError,e:
print >>sys.stderr, "Execution failed:", e
def mymessage(self, title, msg, msgType='info'):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
top = Toplevel()
top.title(title)
t = Label(top, text='\n%s\n' % msgType.upper())
t.pack()
l = Label(top, text=msg)
l.pack()
b = Button(top,text="Ok", command=top.destroy)
b.pack()
def myshowinfo(self, title='', msg=''):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
self.mymessage(title, msg,'info')
root.focus_set()
root.update()
if __name__ == '__main__':
if 1:
root = Tk()
Pmw.initialise(root, size = 16, useTkOptionDb = 1)
root.geometry('500x400+100+100')
root.title("Test application")
app = PumpAdmin(root)
app.drawGui()
app.pack(fill = 'both', expand = 1)
root.deiconify()
root.update()
root.mainloop()
---
#test_subprocess2.py
from Tkinter import *
import os, sys
import subprocess
class AppUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master, relief=SUNKEN, bd=2)
def drawGui(self):
self.drawMenu()
self.drawCanvas()
def drawMenu(self):
self.menubar = Menu(self)
menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="File", menu=menu)
menu.add_command(label="Exit", command=root.destroy)
menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="Test", menu=menu)
menu.add_command(label="Dir list", command=self.dir_list)
try:
self.master.config(menu=self.menubar)
except AttributeError:
# master is a toplevel window (Python 1.4/Tkinter 1.63)
self.master.tk.call(master, "config", "-menu", self.menubar)
def drawCanvas(self):
self.canvas = Canvas(self, bg="white", width=400, height=400,
bd=0, highlightthickness=0)
self.canvas.pack()
def dir_list(self):
'''provide a listing of files in a directory'''
#need to know which system to draw from
curdir = os.getcwd()
try:
#dirlist = subprocess.Popen('ls -l', shell=False,
bufsize=2048, stdout=subprocess.PIPE).stdout
#dirlist,retcode = subprocess.Popen('ls -l',
stdout=subprocess.PIPE).communicate()
#retcode = subprocess.call('ls -l', shell=False)
p = subprocess.Popen(['ls',' -l'], bufsize=2048,
shell=True, close_fds=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(child_stdin, dirlist, retcode) = (p.stdin, p.stdout, p.stderr)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", retcode
print 'error'
self.myshowerror("Error","Sorry, couldn't get a
directory listing")
else:
print 'no error'
#print dirlist
msgList = []
for dir in dirlist:
#print dir
msgList.append(dir)
msg = ''.join(msgList)
#print msg
print 'got to 1'
self.myshowinfo("Directory Listing for %s" % curdir, msg)
print 'got to 2'
self.drawMenu()
except OSError,e:
print >>sys.stderr, "Execution failed:", e
def mymessage(self, title, msg, msgType='info'):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
top = Toplevel()
top.title(title)
t = Label(top, text='\n%s\n' % msgType.upper())
t.pack()
l = Label(top, text=msg)
l.pack()
b = Button(top,text="Ok", command=top.destroy)
b.pack()
def myshowinfo(self, title='', msg=''):
'''a workalike for the tkMessageBox showinfo since the former
results in invisible text in cygwin'''
self.mymessage(title, msg,'info')
root.focus_set()
root.update()
root = Tk()
app = AppUI(root)
app.drawGui()
app.pack()
root.mainloop()
thanks,
--
Stewart Midwinter
(e-mail address removed)
(e-mail address removed)
Skype, GoogleTalk, iChatAV, MSN, Yahoo: midtoad
AIM:midtoad1