Odd Issue when using FlatMenu / FlatMenuBar

I am running into an interesting issue on a program I was asked to look at where using standard accelerator keys to navigate a menu created using wx.lib.agw.flatmenu causes problems. I haven’t been able to test this rigorously however it has only happened when a menu item as the number 2 assigned as an accelerator on Windows 7-64bit, with Python 2.7 and wxPython 2.9.5 installed. Here is the traceback from the error.

python accel_test.py

[‘Menu Item: Test 1, 101’, ‘Menu Item: Test 2, 102’, ‘Menu Item: Test 3, 103’,

Menu Item: Test 4, 104’]

101

Traceback (most recent call last):

File “accel_test.py”, line 46, in onMenuClick

print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()

AttributeError: ‘MainFrame’ object has no attribute ‘FindItem’

To me it appears that 2 is being used by the frame as an accelerator, but it doesn’t quite make sense as to why or how that could happen. Has anyone else run into this or similar errors and been able to resolve it easily?

accel_test.py (1.94 KB)

machine (which I always find reassuring!) I'm using wxPython 3.0, so I had
to comment out your "wxversion.select('2.9'); at least you know it's not
limited to one version.
I also extended your list to 9 items, and - like your experience - it only
chokes on #2. Also, #2 works just fine if you click File/2; it only chokes
if you type the number 2.

None of which gets you closer to a solution - but it does rule out some
blind alleys.

···

On Tue, Aug 4, 2015 at 1:05 PM, Mike Stover <hakugin.gin@gmail.com> wrote:

I am running into an interesting issue on a program I was asked to look at
where using standard accelerator keys to navigate a menu created using
wx.lib.agw.flatmenu causes problems. I haven't been able to test this
rigorously however it has only happened when a menu item as the number 2
assigned as an accelerator on Windows 7-64bit, with Python 2.7 and wxPython
2.9.5 installed. Here is the traceback from the error.

> python accel_test.py
['Menu Item: Test 1, 101', 'Menu Item: Test 2, 102', 'Menu Item: Test 3,
103',
Menu Item: Test 4, 104']
101
Traceback (most recent call last):
  File "accel_test.py", line 46, in onMenuClick
    print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()
AttributeError: 'MainFrame' object has no attribute 'FindItem'

To me it appears that 2 is being used by the frame as an accelerator, but
it doesn't quite make sense as to why or how that could happen. Has anyone
else run into this or similar errors and been able to resolve it easily?

I don't have any insight, unfortunately, but I can duplicate it on my

Hi Mike,

I am running into an interesting issue on a program I was asked to look at where using standard accelerator keys to navigate a menu created using wx.lib.agw.flatmenu causes problems. I haven't been able to test this rigorously however it has only happened when a menu item as the number 2 assigned as an accelerator on Windows 7-64bit, with Python 2.7 and wxPython 2.9.5 installed. Here is the traceback from the error.

> python accel_test.py
['Menu Item: Test 1, 101', 'Menu Item: Test 2, 102', 'Menu Item: Test 3, 103',
Menu Item: Test 4, 104']
101
Traceback (most recent call last):
  File "accel_test.py", line 46, in onMenuClick
    print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()
AttributeError: 'MainFrame' object has no attribute 'FindItem'

To me it appears that 2 is being used by the frame as an accelerator, but it doesn't quite make sense as to why or how that could happen. Has anyone else run into this or similar errors and been able to resolve it easily?

Can also confirm this problem with 3.0.2 classic on Py2.7.

I added an additional print in the handler, i.e.:

     def onMenuClick(self, evt):
         print(evt.GetId()) # Shows the correct menu ID
         print(evt.GetEventObject())
         print(evt.GetEventObject().FindItem(evt.GetId()).GetLabel())

And this shows that the EventObject is different for 2:
3.0.2.0 msw (classic)
['Menu Item: Test 1, 101', 'Menu Item: Test 2, 102', 'Menu Item: Test 3, 103', 'Menu Item: Test 4, 104']
101
<wx.lib.agw.flatmenu.FlatMenu; proxy of <Swig Object of type 'wxPopupWindow *' at 0x390a598> >
TEST 1
101
<__main__.MainFrame; proxy of <Swig Object of type 'wxFrame *' at 0x3d72440> >

I also don't get it why the ID for 2 I get is 101, should be 102, no?

Werner

···

On 8/4/2015 22:05, Mike Stover wrote:

Even manually binding the menu items instead of using [self.Bind(wx.EVT_MENU, self.onMenuClick, menuOpt) for menuOpt in menu_list] does not seem to help. I find it odd that it only happens with the number 2 and not other numbers.

···

On Tuesday, August 4, 2015 at 4:05:52 PM UTC-4, Mike Stover wrote:

I am running into an interesting issue on a program I was asked to look at where using standard accelerator keys to navigate a menu created using wx.lib.agw.flatmenu causes problems. I haven’t been able to test this rigorously however it has only happened when a menu item as the number 2 assigned as an accelerator on Windows 7-64bit, with Python 2.7 and wxPython 2.9.5 installed. Here is the traceback from the error.

python accel_test.py

[‘Menu Item: Test 1, 101’, ‘Menu Item: Test 2, 102’, ‘Menu Item: Test 3, 103’,

Menu Item: Test 4, 104’]

101

Traceback (most recent call last):

File “accel_test.py”, line 46, in onMenuClick

print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()

AttributeError: ‘MainFrame’ object has no attribute ‘FindItem’

To me it appears that 2 is being used by the frame as an accelerator, but it doesn’t quite make sense as to why or how that could happen. Has anyone else run into this or similar errors and been able to resolve it easily?

The ID should be 102, which is what shows when that option is clicked, but for some reason when the accelerator key is used 101 is emitted instead. Seems like a strange bug that I have been unable to trace down thus far.

···

On Wednesday, August 5, 2015 at 6:28:16 AM UTC-4, werner wrote:

Hi Mike,

On 8/4/2015 22:05, Mike Stover wrote:

I am running into an interesting issue on a program I was asked to
look at where using standard accelerator keys to navigate a menu
created using wx.lib.agw.flatmenu causes problems. I haven’t been able
to test this rigorously however it has only happened when a menu item
as the number 2 assigned as an accelerator on Windows 7-64bit, with
Python 2.7 and wxPython 2.9.5 installed. Here is the traceback from
the error.

python accel_test.py

[‘Menu Item: Test 1, 101’, ‘Menu Item: Test 2, 102’, ‘Menu Item: Test
3, 103’,

Menu Item: Test 4, 104’]

101

Traceback (most recent call last):

File “accel_test.py”, line 46, in onMenuClick

print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()

AttributeError: ‘MainFrame’ object has no attribute ‘FindItem’

To me it appears that 2 is being used by the frame as an accelerator,
but it doesn’t quite make sense as to why or how that could happen.
Has anyone else run into this or similar errors and been able to
resolve it easily?

Can also confirm this problem with 3.0.2 classic on Py2.7.

I added an additional print in the handler, i.e.:

 def onMenuClick(self, evt):

     print(evt.GetId()) # Shows the correct menu ID

     print(evt.GetEventObject())

     print(evt.GetEventObject().FindItem(evt.GetId()).GetLabel())

And this shows that the EventObject is different for 2:

3.0.2.0 msw (classic)

[‘Menu Item: Test 1, 101’, ‘Menu Item: Test 2, 102’, ‘Menu Item: Test 3,
103’, ‘Menu Item: Test 4, 104’]

101

<wx.lib.agw.flatmenu.FlatMenu; proxy of <Swig Object of type
‘wxPopupWindow *’ at 0x390a598> >

TEST 1

101

<main.MainFrame; proxy of <Swig Object of type ‘wxFrame *’ at
0x3d72440> >

I also don’t get it why the ID for 2 I get is 101, should be 102, no?

Werner

Mike Stover wrote:

I am running into an interesting issue on a program I was asked to look
at where using standard accelerator keys to navigate a menu created
using wx.lib.agw.flatmenu causes problems. I haven't been able to test
this rigorously however it has only happened when a menu item as the
number 2 assigned as an accelerator on Windows 7-64bit, with Python 2.7
and wxPython 2.9.5 installed. Here is the traceback from the error.

> python accel_test.py
['Menu Item: Test 1, 101', 'Menu Item: Test 2, 102', 'Menu Item: Test 3,
103',
Menu Item: Test 4, 104']
101
Traceback (most recent call last):
   File "accel_test.py", line 46, in onMenuClick
     print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()
AttributeError: 'MainFrame' object has no attribute 'FindItem'

To me it appears that 2 is being used by the frame as an accelerator,
but it doesn't quite make sense as to why or how that could happen. Has
anyone else run into this or similar errors and been able to resolve it
easily?

Yes, it looks like something (probably in flatmenu) is setting an accelerator table on the frame that includes an entry for '2' with an ID of 101, and that 2 is handled before the one in the FlatMenu. Adding the following at the end of __init__ confirms this:

         tbl = wx.AcceleratorTable()
         self.SetAcceleratorTable(tbl)

as it will then not do anything for '2' unless the popup menu is shown, and it then has the correct ID and EventObject. Unfortunately doing that also eliminates the Alt-F accelerator for showing the menu. I don't have time to dig any deeper but maybe this will help one of you track down the source of the problem.

···

--
Robin Dunn
Software Craftsman

Thank you Robin, I had not thought of doing that for troubleshooting. I’ll keep looking through the flatmenu source code and continue trying to find what could be causing this.

···

On Monday, August 10, 2015 at 8:50:06 PM UTC-4, Robin Dunn wrote:

Mike Stover wrote:

I am running into an interesting issue on a program I was asked to look

at where using standard accelerator keys to navigate a menu created

using wx.lib.agw.flatmenu causes problems. I haven’t been able to test

this rigorously however it has only happened when a menu item as the

number 2 assigned as an accelerator on Windows 7-64bit, with Python 2.7

and wxPython 2.9.5 installed. Here is the traceback from the error.

python accel_test.py

[‘Menu Item: Test 1, 101’, ‘Menu Item: Test 2, 102’, 'Menu Item: Test 3,

103’,

Menu Item: Test 4, 104’]

101

Traceback (most recent call last):

File “accel_test.py”, line 46, in onMenuClick

 print evt.GetEventObject().FindItem(evt.GetId()).GetLabel()

AttributeError: ‘MainFrame’ object has no attribute ‘FindItem’

To me it appears that 2 is being used by the frame as an accelerator,

but it doesn’t quite make sense as to why or how that could happen. Has

anyone else run into this or similar errors and been able to resolve it

easily?

Yes, it looks like something (probably in flatmenu) is setting an
accelerator table on the frame that includes an entry for ‘2’ with an ID
of 101, and that 2 is handled before the one in the FlatMenu. Adding
the following at the end of init confirms this:

     tbl = wx.AcceleratorTable([])

     self.SetAcceleratorTable(tbl)

as it will then not do anything for ‘2’ unless the popup menu is shown,
and it then has the correct ID and EventObject. Unfortunately doing
that also eliminates the Alt-F accelerator for showing the menu. I
don’t have time to dig any deeper but maybe this will help one of you
track down the source of the problem.


Robin Dunn

Software Craftsman

http://wxPython.org

Mike Stover wrote:

...

Yes, it looks like something (probably in flatmenu) is setting an accelerator table on the frame that includes an entry for '2' with an ID of 101, and that 2 is handled before the one in the FlatMenu. Adding the following at the end of __init__ confirms this:

        tbl = wx.AcceleratorTable()
        self.SetAcceleratorTable(tbl)

as it will then not do anything for '2' unless the popup menu is shown, and it then has the correct ID and EventObject. Unfortunately doing that also eliminates the Alt-F accelerator for showing the menu. I don't have time to dig any deeper but maybe this will help one of you track down the source of the problem.

Hhm, I can't find a "102" id or "&2" in the flatmenu code.

Found a work around to make it work:

         self.f_menu = FM.FlatMenu()
         self.menuBar.Append(self.f_menu, '&File')

Doing the menuBar.Append just after self.f_menu is created makes it work, still chasing why that makes it work.

Werner

···

On 8/11/2015 2:49, Robin Dunn wrote:

Hi,

The problem seems to be in FlatMenuBar.UpdateAcceleratorTable.

If I comment line 3437, this is the real problem, just this one makes it work, basically it is the same as moving the menuBar.Append call I mentioned in my previous post.

#updatedTable = item.GetMenu().GetAccelArray() + updatedTable

The following stuff is doing work which is not needed, just using updateTable when creating the AcceleratorTable is enough.
comment lines 3460 to 3464
         #entries = [wx.AcceleratorEntry() for ii in xrange(len(updatedTable))]

         ## Add the new menu items
         #for i in xrange(len(updatedTable)):
             #entries[i] = updatedTable[i]

and change line 3466 and comment 3467:
         table = wx.AcceleratorTable(updatedTable)
         #del entries

I can create a PR based on the above, but I am not sure if I am not missing something in all of this. Especially why is it only failing with the "2" and not with all menu item accelerators.

Werner

I just got the time to look through the code myself, good catch.

···

On Wednesday, August 12, 2015 at 11:42:47 AM UTC-4, werner wrote:

Hi,

The problem seems to be in FlatMenuBar.UpdateAcceleratorTable.

If I comment line 3437, this is the real problem, just this one makes it
work, basically it is the same as moving the menuBar.Append call I
mentioned in my previous post.

#updatedTable = item.GetMenu().GetAccelArray() + updatedTable

The following stuff is doing work which is not needed, just using
updateTable when creating the AcceleratorTable is enough.

comment lines 3460 to 3464

     #entries = [wx.AcceleratorEntry() for ii in

xrange(len(updatedTable))]

     ## Add the new menu items

     #for i in xrange(len(updatedTable)):

         #entries[i] = updatedTable[i]

and change line 3466 and comment 3467:

     table = wx.AcceleratorTable(updatedTable)

     #del entries

I can create a PR based on the above, but I am not sure if I am not
missing something in all of this. Especially why is it only failing
with the “2” and not with all menu item accelerators.

Werner

Hi Mike and Robin,

I just got the time to look through the code myself, good catch.

It was a lot of trial an error, as I could not recreate the problem when running it through the debugger (WingIDE). In the debugger even the "2" accelerator worked, so it might be some timing issue.

Still don't understand why it only happens for the "2".

Would like to see if the Phoenix problem could also be fixed, i.e. the test for flatmenu is crashing in Py2.7 and Py3.4 and it crashes also when one selects a menu. Anyone has an idea what this might be caused by?

Werner

···

On 8/13/2015 20:07, Mike Stover wrote:

Hi,

...

Would like to see if the Phoenix problem could also be fixed, i.e. the test for flatmenu is crashing in Py2.7 and Py3.4 and it crashes also when one selects a menu. Anyone has an idea what this might be caused by?

Oops, the reason ( "PushEventHandler" found by Metalicow some time ago) for this is known and it is on Robin's list.

Werner

···

On 8/14/2015 8:52, Werner wrote:

I must have missed that discovery. For the time being I will use the suggestions here as the free time I had for troubleshooting this has been drastically reduced.

···

On Friday, August 14, 2015 at 5:34:34 AM UTC-4, werner wrote:

Hi,

On 8/14/2015 8:52, Werner wrote:

Would like to see if the Phoenix problem could also be fixed, i.e. the
test for flatmenu is crashing in Py2.7 and Py3.4 and it crashes also
when one selects a menu. Anyone has an idea what this might be caused
by?

Oops, the reason ( “PushEventHandler” found by Metalicow some time ago)
for this is known and it is on Robin’s list.

Werner

Hi Guys,

Did you find a workaround for this issue? I’m facing a very similar issue.

Thanks,

Emad

···

On Friday, August 14, 2015 at 12:24:58 PM UTC-7, Mike Stover wrote:

I must have missed that discovery. For the time being I will use the suggestions here as the free time I had for troubleshooting this has been drastically reduced.

On Friday, August 14, 2015 at 5:34:34 AM UTC-4, werner wrote:

Hi,

On 8/14/2015 8:52, Werner wrote:

Would like to see if the Phoenix problem could also be fixed, i.e. the
test for flatmenu is crashing in Py2.7 and Py3.4 and it crashes also
when one selects a menu. Anyone has an idea what this might be caused
by?

Oops, the reason ( “PushEventHandler” found by Metalicow some time ago)
for this is known and it is on Robin’s list.

Werner

Hi Guys,

I think this workaround works.

In the flatmenu.py file the following change is done in method AddItem. The issue now removed.

if accel:

accel.Set(accel.GetFlags(), accel.GetKeyCode(), menuItem.GetId())

self._accelArray.append(accel)

if accel.GetFlags()>0

accel.Set(accel.GetFlags(), accel.GetKeyCode(), menuItem.GetId())

self._accelArray.append(accel)

Thanks,

Emad

···

On Friday, April 15, 2016 at 2:02:25 PM UTC-7, Emad Dlala wrote:

Hi Guys,

Did you find a workaround for this issue? I’m facing a very similar issue.

Thanks,

Emad

On Friday, August 14, 2015 at 12:24:58 PM UTC-7, Mike Stover wrote:

I must have missed that discovery. For the time being I will use the suggestions here as the free time I had for troubleshooting this has been drastically reduced.

On Friday, August 14, 2015 at 5:34:34 AM UTC-4, werner wrote:

Hi,

On 8/14/2015 8:52, Werner wrote:

Would like to see if the Phoenix problem could also be fixed, i.e. the
test for flatmenu is crashing in Py2.7 and Py3.4 and it crashes also
when one selects a menu. Anyone has an idea what this might be caused
by?

Oops, the reason ( “PushEventHandler” found by Metalicow some time ago)
for this is known and it is on Robin’s list.

Werner