Menu

Pmw menubar problem in cygwin

Help
2006-01-05
2013-02-21
  • Stewart Midwinter

    (cross-posted to tkinter-discuss and python-list)

    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,
    s

     
    • Greg McFarlane

      Greg McFarlane - 2006-01-16

      Don't jump to conclusions about the problem being "obviously" with Pmw :)

      I could not run your scripts because I do not have the "subprocess" module.  So for testing, I removed the references to subprocess and replaced "dirlist" with ('a', 'b', 'c).

      Both scripts worked as expected. I could select the Test -> Directory List menu item, then click OK in the new toplevel and then do it all again.  The menus worked fine all the time.

      I suspect something funny in the subprocess module.

       

Log in to post a comment.