pythonpython-3.xmenuseparatorpystray

How to create a menu separator in pystray


I am trying to create a pystray menu separator, but I am having a hard time doing so. I have searched here on SO and in its documentation, which I find super confusing and unhelpful and I even tried to read the Menu class:

class Menu(object):
    """A description of a menu.

    A menu description is immutable.

    It is created with a sequence of :class:`Menu.Item` instances, or a single
    callable which must return a generator for the menu items.

    First, non-visible menu items are removed from the list, then any instances
    of :attr:`SEPARATOR` occurring at the head or tail of the item list are
    removed, and any consecutive separators are reduced to one.
    """
    #: A representation of a simple separator
    SEPARATOR = MenuItem('- - - -', None)

    def __init__(self, *items):
        self._items = tuple(items)

In which I found the following representation, which I used like this:

sep = pystray.MenuItem("- - - -", None)

but instead of creating a separator, it created a menu item with this text: - - - -

You can find a minimal reproducible example below:

import pystray
from PIL import Image
def item1_action(icon, item):
    print("Item 1 clicked")
def item2_action(icon, item):
    print("Item 2 clicked")
def quit_action(icon, item):
    print("Quit clicked")

item1 = pystray.MenuItem("Item 1", item1_action)
item2 = pystray.MenuItem("Item 2", item2_action)
sep = pystray.MenuItem("- - - -", None)
quit_item = pystray.MenuItem("Quit", quit_action)
menu = (item1, item2,s, quit_item)
image = Image.open('icon.png')
icon = pystray.Icon("test", image, "test", menu)
icon.run()

Solution

  • You have correctly identified the point at which the use of the separator is indicated. However, you should specifically use the SEPARATOR attribute instead of its assigned value because someone might actually want to create a menu item with four hyphens, and it wouldn't be appropriate for pystray to automatically convert it to a separator against their will.

    That being said, you need to replace this:

    sep = pystray.MenuItem("- - - -", None)
    

    with this:

    sep = pystray.Menu.SEPARATOR