Search code examples
pythontkinterpystray

OSError: [WinError 6] The handle is invalid. [Python]


Hey i am trying to make a application working in windows. It's basically adjusting your monitor brightness. There is a function provides minimize application. So i have issue about minimize.

When clicking second time to minimize button getting error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\user\OneDrive\Desktop\Python_simple_projects\Desktop_brightness_app\test.py", line 249, in minimize_app
    self.icon.run()
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\pystray\_base.py", line 212, in run
    self._run()
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\pystray\_win32.py", line 120, in _run
    self._hwnd = self._create_window(self._atom)
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\pystray\_win32.py", line 244, in _create_window
    hwnd = win32.CreateWindowEx(
  File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages\pystray\_util\win32.py", line 204, in _err
    raise ctypes.WinError()
OSError: [WinError 6] The handle is invalid.

There is a few part of code below:

import ttkbootstrap as tb
import ttkbootstrap as ttk
import PIL.Image
import pystray


class DesktopBrightnessApp:
     def __init__(self):
            self.minimize_button = tb.Button(self.root, text="Minimize", 
               command=self.minimize_app)
               self.minimize_button.place(x=215, y=200)

            self.icon = pystray.Icon('icon', img, menu=pystray.Menu(
                pystray.MenuItem("Open GUI", self.on_move_clicked),
                pystray.MenuItem("Exit", self.on_move_clicked)
                ))

     def on_move_clicked(self, icon, item):

            if str(item) == "Open GUI":
               icon.stop()
               self.root.deiconify()

            elif str(item) == "Exit":
               icon.stop()
               self.root.destroy()

     def minimize_app(self):
            self.root.withdraw()
            self.icon.run()
        

     def run(self):
         self.root.mainloop()


if __name__ == "__main__":
    app = DesktopBrightnessApp()
    app.run()

Solution

  • When icon.stop() is executed, you need to create a new instance of pystray.Icon in order to run icon.run():

    class DesktopBrightnessApp:
        def __init__(self):
            ...
            # convert img to instance variable self.img
            self.img = ...
    
            ...
            # create the icon menu once
            self.menu = pystray.Menu(
                pystray.MenuItem("Open GUI", self.on_move_clicked),
                pystray.MenuItem("Exit", self.on_move_clicked)
            )
            # don't create instance of pystray.Icon here
    
        ...
        def minimize_app(self):
            self.root.withdraw()
            # create instance of pystray.Icon here
            self.icon = pystray.Icon('icon', self.img, menu=self.menu)
            self.icon.run()
    
        ...