Python pystray update_menu, use variable text for item

319 Views Asked by At

I want to change the text for an item variably. to do this, i tried to update the menu using update_menu(). unfortunately, this didn't work and i couldn't find anything more detailed in the pystray documentation. I hope you can help me. thank you.

from pystray import Icon as icon, Menu as menu, MenuItem as item
import PIL.Image

image = PIL.Image.new('RGB', (100, 100), 255)

adapter = 'before'
def test():
    global ps
    global adapter
    adapter = 'after'
    ps.update_menu()

ps = icon(name='name', icon=image, menu=menu(
        item(text='Adapter', action=menu(item(text='Test', action=test))),
        item(text=adapter, action=lambda: test()),
        )
    )
ps.run()
1

There are 1 best solutions below

2
On BEST ANSWER

I've got to a similar problem earlier, I wanted to update the submenu while running.
I made a version for what you wanted to adjust:

def test(icon, this_item):
    global adapter
    adapter = 'after'
    global menu_items
    menu_items.pop() # remove last element, here containing 'adapter'
    # add new item with updated adapter value
    menu_items.append(item(text=adapter, action=test))
    icon.update_menu()

menu_items = [
        item(text='Adapter', action=menu(item(text='Test', action=test))),
        item(text=adapter, action=test)
        ]

ps = icon(name='name', icon=image, menu=menu(lambda: menu_items))
ps.run()

The MenuItem takes (*items) so giving it a list with items in a lambda function works to update it later.
You have to alter the menu_items list to your needs and update.
Couldn't figure out tho how to just adjust the text, with a lambda e.g. either.

Found also this example #17, they changed the whole menu each time, but well...


UPDATE: Here's what you wanted, cleaner than my previous answer:

adapter = 'before'
def test(icon, this_item):
    global adapter
    adapter = 'after'
    icon.update_menu()

ps = icon(name='name', icon=image, menu=menu(
        item(text='Adapter', action=menu(item(text='Test', action=test))),
        item(lambda text: adapter, action=test)
        )
)

found here