moses-palmer / pystray

GNU General Public License v3.0
461 stars 57 forks source link

Changing values in runtime using lamda function (documentation) #158

Closed LawMixer closed 4 months ago

LawMixer commented 4 months ago

I've tried what was written in the documentation, and it does not refresh the value in the system tray. Maybe, I did something wrong and I need a second set of eyes to view my errors, any help would be appreciated, thanks!

import pystray
from PIL import Image

image = Image.open("5968322.png")

state = "Start"

def after_click(icon2: pystray.Icon, query):    
    global state 

    if str(query) == "Start":
      print("Starting..")
    elif str(query) == "Stop":
      print("Stopping..")
    elif str(query) == "Quit":
      icon.stop()

    if state == "Start":
      state = "Stop"

    print(state)
    icon.menu = False
    icon.menu = menu

menu = pystray.Menu(
  pystray.MenuItem("Start", action=after_click, checked=lambda item: state), 
  pystray.MenuItem("Quit", action=after_click)
)
icon = pystray.Icon("T", image, "Testing", menu=menu)

icon.run()

Originally posted by @LawMixer in https://github.com/moses-palmer/pystray/issues/157#issuecomment-1936669279

LawMixer commented 4 months ago

Got it to work, but I'm not sure if it's the recommended way to do it. Any feedback would be appreciated, thank you!

import pystray
from PIL import Image

image = Image.open("5968322.png")

state = "Start"

def after_click(icon2: pystray.Icon, query):    
    global state

    if str(query) == "Start":
      print("Starting..")
    elif str(query) == "Stop":
      print("Stopping..")
    elif str(query) == "Quit":
      icon.stop()

    if state == "Start":
      state = "Stop"
    elif state == "Stop":
      state = "Start"

    menu2 = pystray.Menu(
      pystray.MenuItem(state, action=after_click), 
      pystray.MenuItem("Quit", action=after_click)
    )

    icon.menu = menu2

menu = pystray.Menu(
  pystray.MenuItem("Start", action=after_click), 
  pystray.MenuItem("Quit", action=after_click)
)
icon = pystray.Icon("T", image, "Testing", menu=menu)

icon.run()
moses-palmer commented 4 months ago

In your code sample, you construct the menu item with a static text: "Start". Instead provide a lambda lambda *args: state. If you simply pass state, in Python the value is passed, and later modificationa to state do not propagate.

LawMixer commented 4 months ago

Ah, I get it. Just to confirm I got it right, it is pystray.MenuItem(lambda item: state, action=after_click), correct?

moses-palmer commented 4 months ago

Yes, that looks correct.