Hello,

I am having a problem showing a popup menu in my wxpython script on fedora 5 (fc5); this problem does not occur on xp. I am using wxPython-2.6.3.2-1.fc5, unicode version.

I need to add an item to a popup menu after the user selects a file using wx.FileDialog, and then need to show the popup menu immediately after the file selection to inform the user of the files that have been selected thus far.

The popup menu will not show on fc5 if I first display the wx.FileDialog control - if I avoid wx.FileDialog the popup menu appears without a problem.

#!/usr/bin/python 
 
import wx, time, os 
 
thislimit = 5 
thispopupmenu = None 
 
 
def MakeThePopup(self): 
 
    global thispopupmenu 
 
    menu = wx.Menu() 
     
    ids = [] 
     
    for ii in range(thislimit):
        mnuid = wx.NewId() 
        ids.append(mnuid) 
        menu.Append(mnuid, "File " + str(ii+1)) 
     
    menu.AppendSeparator() 
    add_popupmenu_id = 10102 
    ids.append(add_popupmenu_id) 
    menu.Append(add_popupmenu_id, "Add a File") 
 
     
    for daid in ids: 
        wx.EVT_MENU(self, daid, PopupClicked) 
 
    thispopupmenu = menu 
     
### ---   end of MakeThePopup function   --- ### 
 
 
def PopupClicked(event): 
    
    # get the text of the menu item that was clicked
    mnulabel = event.GetEventObject().GetLabel(event.GetId())
    
    # let's be certain that a menu click is being processed 
    daframe.SetTitle(mnulabel + ' - ' + str(time.time())) 
    
    # activate wx.FileDialog if appropriate popup menu item is clicked 
    if (mnulabel == "Add a File"): 
        global thislimit 
        thislimit = thislimit + 1 
        daframe.SetTitle(mnulabel)
        dlg = wx.FileDialog(daframe, message="Select a File:",\
                        defaultDir=os.getcwd(), defaultFile="",\
                        wildcard="All files (*.*)|*.*",style=wx.OPEN)
                            
        ###  uncomment the following 2 lines of code and
        ###  the popup menu will not appear on fc5    
        
        #if dlg.ShowModal() == wx.ID_OK:
        #    thisresult = "a file was selected"
        
        ###  ######################
            
        # make the poup menu
        MakeThePopup(daframe.button)
        
        # show the popup menu over the button
        daframe.button.PopupMenu(thispopupmenu,wx.Point(5,5))
        # the popup fails to show if a wx.FileDialog has
        # been activated previously
         
        return True 
    
     
    event.Skip() 
     
### ---  end of PopupClicked function   --- ###     
 
 
class DisFrame(wx.Frame): 
    def __init__(self, *args, **kwargs): 
        wx.Frame.__init__(self, *args, **kwargs) 
        
        # make a panel with a button 
        panel = wx.Panel(self) 
        self.button = wx.Button(panel, -1, "Show popup menu") 
        self.button.Bind(wx.EVT_BUTTON, self.ButtonClicked) 
        bs = wx.BoxSizer(wx.HORIZONTAL) 
        bs.Add(self.button,0,wx.ALL,30) 
        panel.SetSizer(bs) 
         
        MakeThePopup(self) 
         
         
    def ButtonClicked(self, event): 
        
        # make the popup 
        MakeThePopup(self)
        
        # show the popup over the button 
        self.button.PopupMenu(thispopupmenu) 
     
        event.Skip() 
 
### ---  end of DisFrame class   --- ### 
 
 
 
if __name__ == '__main__': 
    app = wx.App() 
    daframe = DisFrame(None) 
    daframe.Show() 
    app.MainLoop()

The popup menu appears if running the above script on fc5.

However, if I uncomment the 2 lines of code that show the wx.FileDialog, the popup fails to appear on fc5 and I need to click 'Stop Executing' after closing the application if running the script through SciTE.

How can I show the popup menu after activating a wx.FileDialog control ?

Any help will be appreciated. Thanks.

_

You might have to destroy the dialog after it has been used:

###  uncomment the following 2 lines of code and
        ###  the popup menu will not appear on fc5    
        
        if dlg.ShowModal() == wx.ID_OK:
            # do something
            thisresult = "a file was selected"
        
        dlg.Destroy()
        
        ###  ######################

Thanks for the tip bumsfeld.

dlg.Destroy() should have been there (silly oversight on my part).

Unfortunately the popup menu still fails to appear on fc5 if activating wx.FileDialog and then destroying the dialog.

The program seems to 'hang' (though it's still functional) and requires using SciTE's 'Stop Executing' command to completely kill the running process.

Very puzzling.

I don't have Fedora, so I can't see the effect, but check if Refresh() or Update() will help ...

###  uncomment the following 2 lines of code and
        ###  the popup menu will not appear on fc5
        
        if dlg.ShowModal() == wx.ID_OK:
            # do something
            thisresult = "a file was selected"
        
        dlg.Destroy()
        daframe.Refresh()  # next event
        daframe.Update()   # immediate
        
        ###  ######################

Followed your advice vegaseat, but still no luck - popup menu does not show on fc5 if I use a wx.FileDialog:

if dlg.ShowModal() == wx.ID_OK:
    thisresult = "a file was selected"
dlg.Destroy()
daframe.Refresh()
daframe.Update()

My feable attempts to debug the problem have revealed that the popup menu is apparently created without a problem, but that the problem occurs when the program tries to show it above the button:

# make the popup menu
MakeThePopup(daframe.button)
daframe.SetTitle('popup menu is created')
        
# show the popup menu over the button
daframe.button.PopupMenu(thispopupmenu,wx.Point(5,5))
daframe.SetTitle('showing popup menu')

The above always produces a window title that reads 'popup menu is created' when a wx.FileDialog is used on fc5.

The title never reads 'showing popup menu' when using a file dialog box on fc5, indicating that the problem lies with the program's attempt to display the popup menu.

Are we any closer at finding a solution ?

_

I have made a simpler version of this program in the hope that someone will be able to offer a solution.

This version simply displays a message box after clicking a button, and then within the same function attempts to display a popup menu.

The popup menu will only appear on fc5 if you avoid displaying the message box:

#!/usr/bin/python

import wx, random


def PopupClicked(event):
    
    daframe.SetTitle(str(random.randint(0,100)))    
    event.Skip()
    


class DisFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        
        # make a panel with a button
        panel = wx.Panel(self)
        self.button = wx.Button(panel, -1, "Show popup menu")
        self.button.Bind(wx.EVT_BUTTON, self.ButtonClicked)
        bs = wx.BoxSizer(wx.HORIZONTAL)
        bs.Add(self.button,0,wx.ALL,30)
        panel.SetSizer(bs)
        random.seed()
        
        
    def ButtonClicked(self, event):

        dlg = wx.MessageDialog(daframe,
        message='a message',caption=' ',\
        style=wx.OK|wx.ICON_INFORMATION)
        
        # the popup menu will not appear if
        # this message dialog is shown
        dlg.ShowModal()
        dlg.Destroy()
        # comment-out the above 2 lines and
        # the popup menu will appear
                
        # make and show a popup menu
        menu = wx.Menu()
        menu.Append(101, " menu item 1 ")
        wx.EVT_MENU(self, 101, PopupClicked)
        self.PopupMenu(menu)
        menu.Destroy()
        
        event.Skip()



if __name__ == '__main__':
    app = wx.App()
    daframe = DisFrame(None)
    daframe.Show()
    app.MainLoop()

The same problem occurs whether you display a message box, color dialog or file dialog - the popup menu will only appear if you avoid displaying any type of dialog control beforehand.

How can I display the popup menu on fc5 after displaying the message box ?

_

An initial observation, your popup appears at the location of the dialog box, not in the frame. Is it associated with the wrong parent?

Thanks for the response vegaseat.

The popup fails to show whether I associate it with the main frame or the button (self.button).

I've experienced other problems with the popup menu on fc5 in relation to assigning id numbers via wx.NewId() during the creation of a popup, whereas there were no problems on xp.

Extremely frustrating. Thanks for the input.

_

The following solution was provided by Robin Dunn on a different forum, and makes use of wx.CallAfter():

#!/usr/bin/python

import wx, random

def PopupClicked(event):
      daframe.SetTitle(str(random.randint(0,100)))
      event.Skip()
  
class DisFrame(wx.Frame):
   def __init__(self, *args, **kwargs):
       wx.Frame.__init__(self, *args, **kwargs)
       # make a panel with a button
       panel = wx.Panel(self)
       self.button = wx.Button(panel, -1, "Show popup menu")
       self.button.Bind(wx.EVT_BUTTON, self.ButtonClicked)
       bs = wx.BoxSizer(wx.HORIZONTAL)
       bs.Add(self.button,0,wx.ALL,30)
       panel.SetSizer(bs)
       random.seed()

   def ButtonClicked(self, event):
       dlg = wx.MessageDialog(daframe,
                              message='a message',caption=' ',\
                              style=wx.OK|wx.ICON_INFORMATION)
       dlg.ShowModal()
       dlg.Destroy()
       wx.CallAfter(self.DoPopupMenu)
       

   def DoPopupMenu(self):
       menu = wx.Menu()
       menu.Append(101, " menu item 1 ")
       wx.EVT_MENU(self, 101, PopupClicked)
       self.button.PopupMenu(menu, wx.Point(5,5))
       menu.Destroy()


if __name__ == '__main__':
   app = wx.App()
   daframe = DisFrame(None)
   daframe.Show()
   app.MainLoop()

_

Thanks for letting us know, interesting solution!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.