moses-palmer / pystray

GNU General Public License v3.0
479 stars 59 forks source link

Creating a Menu from a list works for Icon (main menu) but not for Menu (submenu) #140

Open AnAnalogGuy opened 1 year ago

AnAnalogGuy commented 1 year ago

I am dynamically creating a menu including one submenu, both with a couple of items. The submenu as well as the menu are created the same way as a list object and then being instanced as a pystray.Menu object.

The submenu

menu_intervals = []
for intervals_data in intervals:
    menu_items_checked_state[intervals.get(intervals_data)] = not MenuItem.checked
    menu_intervals.append(MenuItem(intervals.get(intervals_data), on_click_interval(Icon, intervals.get(intervals_data),
                        int(intervals_data)), default=False, checked=lambda MenuItem: menu_items_checked_state[MenuItem.text]))
    interval_menu_counter += 1

The Menu

menuItems = []
....
menuItems.append(MenuItem("Toggle Audio Feedback", clicked_toggle_audio))
menuItems.append(MenuItem("Web Interface", clicked_home))
menuItems.append(Menu.SEPARATOR)
menuItems.append(MenuItem("Check for Update", clicked_update))
....

And then adding it all together:

menuItems.append(MenuItem("Auto Position Change", Menu(menu_intervals)))
systray_icon = Icon("Application", image_default, menu=menuItems)

From the documentation:

submenu The submenu, if any, that is attached to this menu item. Either a submenu or an action can be passed as the second argument to the constructor. The submenu must be an instance of Menu.

While creating and adding a Menu to Icon is working this way, it's running into a runtime error doing the same for Menu used as a submenu.

AnAnalogGuy commented 1 year ago

To make it short:

Instead of menuItems.append(MenuItem("Auto Position Change", Menu(menu_intervals))) it needs to be menuItems.append(MenuItem("Auto Position Change", Menu(lambda: menu_intervals)))

To highlight the difference: Menu(lambda: menu_intervals)

@moses-palmer This is quite hard to understand from the docs. I'd like to suggest to add a related example.