<!--Github Markdown doc : https://docs.github.com/fr/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax-->
# What is tray_manager ?
`tray_manager` is a package used for creating a system tray icon, based on pystray (https://github.com/moses-palmer/pystray by Moses Palmér), this package is an "easier" version of pystray to manipulate as it's based on the use of objects.
# How do I install it ?
`tray_manager` is publisehd on PyPi (https://pypi.org/project/tray-manager/) and can be downloaded by using the following command in your terminal :
```shell
pip install tray-manager
```
> [!NOTE]
> You need to have **python** installed on your computer
# Usage
1. [Create and use a TrayManager object](https://github.com/Adastram1/tray_manager/blob/main/README.md#create-and-use-a-traymanager-object)
2. [Create and interact with Items](https://github.com/Adastram1/tray_manager/blob/main/README.md#create-and-interact-with-items)
3. [Add items to the Menu](https://github.com/Adastram1/tray_manager/blob/main/README.md#add-the-items-to-the-menu)
4. [Customize the TrayManager object](https://github.com/Adastram1/tray_manager/blob/main/README.md#customize-the-traymanager-object)
5. [Customize and edit the items](https://github.com/Adastram1/tray_manager/blob/main/README.md#customize-and-edit-the-items)
6. [Check for OS supported features](https://github.com/Adastram1/tray_manager/blob/main/README.md#check-for-os-supported-features)
7. [Notifications](https://github.com/Adastram1/tray_manager/blob/main/README.md#notifications-currently-unavaible) [CURRENTLY UNAVAIBLE]
8. [Advanced settings](https://github.com/Adastram1/tray_manager/blob/main/README.md#advanced-settings)
## Create and use a TrayManager Object
The main object of the librairy is the `tray_manager.TrayManager` object, it is the central element and can be considered as the icon in the system tray itself, it contains all the elements of our app.
To create one, you need to import the `tray_manager.TrayManager` class and create a tray object as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager(app_name="My App")
```
To stop the app, you need to use the `.kill()` function as followed :
> [!NOTE]
> The `.kill()` function returns all the items that are contained in the menu as a list of items
```python
from tray_manager import TrayManager, Label, Button
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_menu = my_tray.menu
def my_callback():
print("Hello")
my_label = Label("My Label")
my_button = Button("My Button", my_callback)
my_menu.add(my_label)
my_menu.add(my_button)
my_tray.kill()
-> [my_label, my_button]
```
> [!IMPORTANT]
> The Menu and TrayManager objects that you've killed will become useless
> [!WARNING]
> Creating a `tray_manager.TrayManager` object will run it's inner loop as soon as it is created. This means that creating a `tray_manager.TrayManager` object will block the rest of your code. To prevent that from happening, you have 2 options :
>
> 1. You can specify a function as the `setup` argument of the `tray_manager.TrayManager` object, this function will be started in a new thread when creating your object.
>
> 2. **(Windows only)** If you're on Windows and you don't worry about compatibility with other platforms, you can set the `run_in_separate_thread` argument of the `tray_manager.TrayManager` object to `True`, this will start the `tray_manager` loop in a new thread and the rest of your code will correctly be executed in the main loop.
## Create and interact with Items
The items are the elements of your app, they will be displayed in the menu they're added to. Their is different kinds of items that all works in a similar way but each have some specificities.
Here is the list of all the items :
1. [Label](https://github.com/Adastram1/tray_manager/blob/main/README.md#label)
2. [Button](https://github.com/Adastram1/tray_manager/blob/main/README.md#button)
3. [CheckBox](https://github.com/Adastram1/tray_manager/blob/main/README.md#checkbox)
4. [Separator](https://github.com/Adastram1/tray_manager/blob/main/README.md#separator)
5. [Submenu](https://github.com/Adastram1/tray_manager/blob/main/README.md#submenu)
### Label
The label is the most basic item, it is only constituated of a text.
To create one, use the `tray_manager.Label` class as followed :
```python
from tray_manager import Label
my_label = Label("My Label")
```
### Button
The button is like the label item but you can add a callback argument (FunctionType) that will be called when the user clicks on the button. You can also specify some arguments as a tuple that will be passed to your function when the button is clicked.
To create one, use the `tray_manager.Button` class as followed :
```python
from tray_manager import Button
def my_callback(text: str) -> None:
print(text)
my_button = Button("My Button", my_callback, args=("Hello",))
```
### CheckBox
The CheckBox item is a bit more complex than a regular button, it has 2 differents callbacks instead of 1 and different arguments for each, one for when the checkbox switch from the 'Disabled' to 'Enabled' state (Not checked to checked), and one for when it switch from the 'Enabled' to 'Disabled' state (Checked to not checked).
You can 'Disable' the interactions with your checkbox by setting the value of `check_default` to `None`.
> [!NOTE]
> The callback won't be executed if the user clicks on the checkbox when it is disabled.
To create one, use the `tray_manager.CheckBox` class as followed :
```python
from tray_manager import CheckBox
def checked(text: str) -> None:
print(f"In procedure 'checked' : {text}")
def unchecked(text: str) -> None:
print(f"In procedure 'unchecked' : {text}")
my_checkbox = CheckBox("My CheckBox", check_default=False, checked_callback=checked, checked_callback_args=("I'm now checked",),
unchecked_callback=unchecked, unchecked_callback_args=("I'm now unchecked",))
```
To get the current state of the checkbox, you can use the `.get_status()` function as followed :
```python
from tray_manager import CheckBox
my_checkbox = CheckBox("My CheckBox")
my_checkbox.get_status()
-> bool | None
```
You can also set the state of the checkbox by using the `.set_status()` function as followed :
```python
from tray_manager import CheckBox
my_checkbox = CheckBox("My CheckBox")
my_checkbox.set_status(True)
-> Checked
my_checkbox.set_status(False)
-> Unchecked
my_checkbox.set_status(None)
-> Disabled
```
> [!NOTE]
>
> | Checkbox | Status |
> | :---: | :---: |
> | Checked | `True` |
> | Unchecked | `False` |
> | Disabled | `None` |
>
> When the checkbox is disabled, it stays in it's previous state and stop interacting, this means that if the checkbox was checked before being disabled, the checkbox will stay checked but nothing will happen if the user click on it.
### Separator
The separator is a built-in object of Pystray, it doesn't have any parameters.
To create one, use the `tray_manager.Separator` class as followed :
```python
from tray_manager import Separator
my_separator = Separator()
```
### Submenu
The submenu is like a `tray_manager.Menu` object and can contains other items including other submenu.
> [!CAUTION]
> Be carreful when adding submenu into each others as adding a submenu to a submenu that is contained in the submenu you're adding will generate a `tray_manager.CircularAddException` error.
> ```mermaid
> flowchart TD
> A{My Submenu} --> B(My Label)
> A --> C(My Button)
> A --> D{My Second Submenu}
> D --> E(My Second Label)
> D --> F(My Checkbox)
> D --> |❌ tray_manager.CircularAddException| A
> ```
To create one, use the `tray_manager.Submenu` as followed :
```python
from tray_manager import Submenu
my_submenu = Submenu("My Submenu")
```
To add an item to the submenu, use the `.add()` function as followed :
```python
from tray_manager import Submenu, Label
my_submenu = Submenu("My Submenu")
my_label = Label("My Label")
my_submenu.add(my_label)
```
To remove an item from the submenu, use the `.remove()` function as followed :
```python
from tray_manager import Submenu, Label
my_submenu = Submenu("My Submenu")
my_label = Label("My Label")
my_submenu.add(my_label)
my_submenu.remove(my_label)
-> my_label
```
> [!NOTE]
> The `.remove()` function return the item that was removed
To get the items contained in a submenu, use the `.get_items()` function as followed:
```python
from tray_manager import Submenu, Label, Button
def my_callback()
print("Hello")
my_submenu = Submenu("My Submenu")
my_label = Label("My Label")
my_button = Button("My Button", my_callback)
my_submenu.add(my_label)
my_submenu.add(my_button)
my_submenu.get_items()
-> [my_label, my_button]
```
## Add the items to the Menu
The `tray_manager.Menu` is one of the central elements of this library, it works like a submenu and is created automatically when you create a `tray_manager.TrayManager` object as the `tray_manager.TrayManager.menu` object and cannot be removed.
> [!WARNING]
> Check `tray_manager.OsSupport.HAS_MENU` for disponibility on your OS, if your OS doesn't support the menu, the `tray_manager.TrayManager.menu` object will be None.
To use the menu, acces the `tray_manager.TrayManager.menu` object as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_menu = my_tray.menu
```
To add an item to the menu, use the `.add()` function as followed :
```python
from tray_manager import TrayManager, Label
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_menu = my_tray.menu
my_label = Label("My Label")
my_menu.add(my_label)
```
To remove an item from the menu, you can use the `.remove()` function as followed :
```python
from tray_manager import TrayManager, Label
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_menu = my_tray.menu
my_label = Label("My Label")
my_menu.add(my_label)
my_menu.remove(my_label)
-> my_label
```
> [!NOTE]
> The `.remove()` function return the item that was removed.
To get the items contained in a menu, you can use the `.get_items()` function as followed:
```python
from tray_manager import TrayManager, Menu, Label, Button
def my_callback()
print("Hello")
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_menu = my_tray.menu
my_label = Label("My Label")
my_button = Button("My Button", my_callback)
my_menu.add(my_label)
my_menu.add(my_button)
my_menu.get_items()
-> [my_label, my_button]
```
To update the menu items (The items contained inside the menu), use the `.update()` function.
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_menu = my_tray.menu
my_menu.update()
```
> [!NOTE]
> The `.update()` function is triggered automatically every time you edit, add or remove an item from the menu.
## Customize the TrayManager object
You can customize your TrayManager object in different ways such as :
1. [Setting a new name for the app](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-a-new-name-for-the-app)
2. [Setting a new icon for the app](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-a-new-icon-for-the-app)
3. [Hiding / Showing the app in the system tray](https://github.com/Adastram1/tray_manager/blob/main/README.md#hiding--showing-the-app-in-the-system-tray)
### Setting a new name for the app
To set a new name for your app use the `.set_app_name()` function as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_tray.set_app_name("My new App")
```
### Setting a new icon for the app
`tray_manager` use a memory system for icons, to set a new icon for your app, you first need to load it using the `.load_icon()` function, then set the icon as the new icon using the `.set_icon()` function of the `tray_manager.TrayManager` object.
> [!NOTE]
> By default, the icon is a white square of 32x32 pixels.
> The default icon is always loaded in memory and can be set again by passing the `tray_manager.Values.DEFAULT` as the `name` argument of the `.set_icon()` function.
To load an icon, use the `.load_icon()` function and pass it **a file path, a encoded image, a `PIL.Image` object or any file that can be read and interpreted as an image by PIL**. You also need to pass a name that will be used as a key in the icons dictionnary to retreive your icon.
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_tray.load_icon("my_icon_file_path.png", "my_new_icon")
```
> [!WARNING]
> `tray_manager` use a dictionnary to save your loaded icons, this means that loading an image using a name that was already used will overwrite the image that was previously loaded with that name.
> The only exception to this is the default icon that cannot be edited.
To set an icon, use the `.set_icon()` function and pass it the name (key) of your icon that you set when you loaded the icon.
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_tray.load_icon("my_icon_file_path.png", "my_new_icon")
my_tray.set_icon("my_new_icon")
```
### Hiding / Showing the app in the system tray
Instead of killing the `tray_manager.TrayManager` object when you want it to stop being displayed in the system tray and creating a new one once you need it again, you can use the `.show()` and `.hide()` functions of the the `tray_manager.TrayManager` object to control whether the app is visible in the system tray or not.
> [!NOTE]
> You can set the `default_show` argument of the `tray_manager.TrayManager` object to `True` or `False` when creating your `tray_manager.TrayManager` object to define whether the system tray icon will be displayed or not once the object is created.
To show the app in the system tray, use the `.show()` function of the the `tray_manager.TrayManager` object as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_tray.show()
```
To hide the app in the system tray, use the `.hide()` function of the the `tray_manager.TrayManager` object as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_seperate_thread=True)
my_tray.hide()
```
## Customize and edit the items
To edit an already created item, use the `.edit()` function of the item, when doing so, you only need to specify which arguments you want to change, and the others will stay the same as they were.
To edit an item, do as followed :
```python
from tray_manager import Button
def my_first_callback():
print("Hello")
my_button.edit(callback=my_second_callback)
def my_second_callback():
print("World !")
my_button = Button("My Button", my_first_callback)
# When clicking on the button, this will display :
# First click
-> Hello
# Second click
-> World !
```
You can custom the items in different ways such as :
1. [Enabling / Disabling the item (Gray look and non-responsive)](https://github.com/Adastram1/tray_manager/blob/main/README.md#enabling--disabling-the-item-gray-look-and-non-responsive)
2. [Setting the default attribut to the item (Bold look)](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-the-default-attribut-to-the-item-bold-look)
3. [Setting the radio look on the checkbox (A dot instead of a crossmark)](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-the-radio-look-on-the-checkbox-a-dot-instead-of-a-crossmark)
### Enabling / Disabling the item (Gray look and non-responsive)
If you want to display the item but you want it to be non-responsive (for Button, CheckBox and Submenu) and look like a disabled item, you can use the `.enable()` and `.disable()` functions of the item.
> [!NOTE]
> By default, every items are enabled
>
> Every item can be disabled except the separator.
To enable your item, use the `.enable()` function of the item as followed :
```python
from tray_manager import CheckBox
def checked_callback():
print("Checked")
def unchecked_callback():
print("Unchecked")
my_checkbox = CheckBox("My CheckBox", checked_callback=checked_callback, unchecked_callback=unchecked_callback)
my_checkbox.enable()
```
To disable your item, use the `.disable()` function of the item as followed :
```python
from tray_manager import CheckBox
def checked_callback():
print("Checked")
def unchecked_callback():
print("Unchecked")
my_checkbox = CheckBox("My CheckBox", checked_callback=checked_callback, unchecked_callback=unchecked_callback)
my_checkbox.disable()
```
### Setting the default attribut to the item (Bold look)
To make your item the default item of the menu / submenu and give it a bold look, you can set the `default` attribut when creating / editing the item to `True`.
> [!NOTE]
> You can only have 1 default item by menu / submenu. By default, there is no default item.
To set the `default` attribut of the item, do as followed :
When creating the item :
```python
from tray_manager import Label
my_label = Label("My Label", default=True)
```
When editing the item :
```python
from tray_manager import Label
my_label = Label("My Label")
my_label.edit(default=True)
```
### Setting the radio look on the checkbox (A dot instead of a crossmark)
If you want to give a new look to your regular checkbox crossmark, you can set the `use_radio_look` attribut of the CheckBox to `True` when creating / editing the CheckBox.
To set the `use_radio_look` attribut of the item, do as followed :
When creating the item :
```python
from tray_manager import CheckBox
def checked_callback():
print("Checked")
def unchecked_callback():
print("Unchecked")
my_checkbox = CheckBox("My CheckBox", checked_callback=checked_callback, unchecked_callback=unchecked_callback, use_radio_look=True)
```
When editing the item :
```python
from tray_manager import CheckBox
def checked_callback():
print("Checked")
def unchecked_callback():
print("Unchecked")
my_checkbox = CheckBox("My CheckBox", checked_callback=checked_callback, unchecked_callback=unchecked_callback)
my_checkbox.edit(use_radio_look=True)
```
## Check for OS supported features
Before using features of the `tray_manager package`, you **must** check if they are compatible with your OS. To do so, use the `tray_manager.Os_Support` object.
There is 4 differents features that you need to check before using :
1. Os_Support.SUPPORT_MENU
2. Os_Support.SUPPORT_DEFAULT
3. Os_Support.SUPPORT_RADIO
4. Os_Support.SUPPORT_NOTIFICATION [CURRENTLY UNAVAILBE]
To know if your OS support a feature the corresponding `Os_Support` variable must be True.
Example, to check if your OS support the menu, do as followed :
```python
from tray_manager import Os_Support
if Os_Support.SUPPORT_MENU:
print("The menu is supported by your OS")
else:
print("The menu isn't supported by your OS")
```
> [!NOTE]
> Here is a chart of the features that are ***supposed*** and ***not supposed*** to be supported by each OS and backends.
> | Feature \ OS and backend | Windows (win32) | Linux (gtk) | Linux (appindicator) | Linux (ayatana-appindicator) | Linux (xorg) | MacOS (darwin) |
> | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
> | Menu | Supported | Supported | Supported | Supported | Not Supported | Supported |
> | Default | Supported | Supported | Not Supported | Not Supported | Supported | Not Supported |
> | Radio | Supported | Supported | Supported | Supported | Supported | Not Supported |
> | Notification | Currently Unavailbe | Unknown | Uknown | Unknown | Not Supported | Not Supported |
## Notifications [CURRENTLY UNAVAIBLE]
If you want to create a notification on the user's screen, you can use the `tray_manager.TrayManager.notification` object.
To create a notification, use the `.notify()` function of the `tray_manager.TrayManager.notification` object as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_separate_thread=True)
notification = my_tray.notification
notification.notify("My App", "Hello World !")
```
You can specify a delay after which the notification will be removed by passing a value **in seconds** to the `.notify()` function as the `remove_after_s` as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_separate_thread=True)
notification = my_tray.notification
notification.notify("My App", "Hello World !", remove_after_s=10)
# The notification will close by itself after 10 seconds
```
You can also use the `.remove_notification()` function to manually remove the notification as followed :
```python
from tray_manager import TrayManager
my_tray = TrayManager("My App", run_in_separate_thread=True)
notification = my_tray.notification
notification.notify("My App", "Hello World !)
# Some code here
notification.remove_notification()
```
> [!CAUTION]
> By default the notification will **never** close by itself, make sure to close it before creating a new one.
## Advanced settings
### Selecting a backend
If you need specific features, you can set the `backend` argument of the `tray_manager.TrayManager` object to one of the `tray_manager.Backends` values.
> [!NOTE]
> By default pystray will use the best backend avaible on your os.
> [!CAUTION]
> You **MUST** use the backend from the `tray_manager.Backends` class, passing the value of one of the object of the class will raise an error.
>
> You **MUST** also use a backend compatible with you OS.
>
> | OS | Backends |
> | :---: | :---: |
> | Windows | `win32` |
> | MacOS | `darwin` |
> | Linux | `gtk`, `appindicator`, `ayatana-appindicator`, `xorg` |
Raw data
{
"_id": null,
"home_page": "https://github.com/Adastram1/tray_manager",
"name": "tray-manager",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "python, manager, system tray, pystray",
"author": "Adastram",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/a5/21/37ea4e3e02c561d68ab655b975445490d0bc6da93fc9d15bebdc15ee0092/tray_manager-1.0.3.tar.gz",
"platform": null,
"description": "<!--Github Markdown doc : https://docs.github.com/fr/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax-->\n# What is tray_manager ?\n`tray_manager` is a package used for creating a system tray icon, based on pystray (https://github.com/moses-palmer/pystray by Moses Palm\u00e9r), this package is an \"easier\" version of pystray to manipulate as it's based on the use of objects.\n\n# How do I install it ?\n`tray_manager` is publisehd on PyPi (https://pypi.org/project/tray-manager/) and can be downloaded by using the following command in your terminal :\n```shell\npip install tray-manager\n```\n> [!NOTE]\n> You need to have **python** installed on your computer\n\n# Usage\n1. [Create and use a TrayManager object](https://github.com/Adastram1/tray_manager/blob/main/README.md#create-and-use-a-traymanager-object)\n2. [Create and interact with Items](https://github.com/Adastram1/tray_manager/blob/main/README.md#create-and-interact-with-items)\n3. [Add items to the Menu](https://github.com/Adastram1/tray_manager/blob/main/README.md#add-the-items-to-the-menu)\n4. [Customize the TrayManager object](https://github.com/Adastram1/tray_manager/blob/main/README.md#customize-the-traymanager-object)\n5. [Customize and edit the items](https://github.com/Adastram1/tray_manager/blob/main/README.md#customize-and-edit-the-items)\n6. [Check for OS supported features](https://github.com/Adastram1/tray_manager/blob/main/README.md#check-for-os-supported-features)\n7. [Notifications](https://github.com/Adastram1/tray_manager/blob/main/README.md#notifications-currently-unavaible) [CURRENTLY UNAVAIBLE]\n8. [Advanced settings](https://github.com/Adastram1/tray_manager/blob/main/README.md#advanced-settings)\n\n## Create and use a TrayManager Object\nThe main object of the librairy is the `tray_manager.TrayManager` object, it is the central element and can be considered as the icon in the system tray itself, it contains all the elements of our app.\n\nTo create one, you need to import the `tray_manager.TrayManager` class and create a tray object as followed :\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(app_name=\"My App\")\n```\n\nTo stop the app, you need to use the `.kill()` function as followed : \n> [!NOTE]\n> The `.kill()` function returns all the items that are contained in the menu as a list of items\n\n```python\nfrom tray_manager import TrayManager, Label, Button\n\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\nmy_menu = my_tray.menu\n\ndef my_callback():\n print(\"Hello\")\n\nmy_label = Label(\"My Label\")\nmy_button = Button(\"My Button\", my_callback)\n\nmy_menu.add(my_label)\nmy_menu.add(my_button)\n\nmy_tray.kill()\n-> [my_label, my_button]\n```\n> [!IMPORTANT]\n> The Menu and TrayManager objects that you've killed will become useless\n\n> [!WARNING]\n> Creating a `tray_manager.TrayManager` object will run it's inner loop as soon as it is created. This means that creating a `tray_manager.TrayManager` object will block the rest of your code. To prevent that from happening, you have 2 options : \n>\n> 1. You can specify a function as the `setup` argument of the `tray_manager.TrayManager` object, this function will be started in a new thread when creating your object.\n> \n> 2. **(Windows only)** If you're on Windows and you don't worry about compatibility with other platforms, you can set the `run_in_separate_thread` argument of the `tray_manager.TrayManager` object to `True`, this will start the `tray_manager` loop in a new thread and the rest of your code will correctly be executed in the main loop.\n\n## Create and interact with Items\nThe items are the elements of your app, they will be displayed in the menu they're added to. Their is different kinds of items that all works in a similar way but each have some specificities. \n\nHere is the list of all the items :\n1. [Label](https://github.com/Adastram1/tray_manager/blob/main/README.md#label)\n2. [Button](https://github.com/Adastram1/tray_manager/blob/main/README.md#button)\n3. [CheckBox](https://github.com/Adastram1/tray_manager/blob/main/README.md#checkbox)\n4. [Separator](https://github.com/Adastram1/tray_manager/blob/main/README.md#separator)\n5. [Submenu](https://github.com/Adastram1/tray_manager/blob/main/README.md#submenu)\n\n### Label\nThe label is the most basic item, it is only constituated of a text.\n\nTo create one, use the `tray_manager.Label` class as followed :\n\n```python\nfrom tray_manager import Label\nmy_label = Label(\"My Label\")\n```\n\n### Button\nThe button is like the label item but you can add a callback argument (FunctionType) that will be called when the user clicks on the button. You can also specify some arguments as a tuple that will be passed to your function when the button is clicked.\n\nTo create one, use the `tray_manager.Button` class as followed : \n\n```python\nfrom tray_manager import Button\ndef my_callback(text: str) -> None:\n print(text)\n\nmy_button = Button(\"My Button\", my_callback, args=(\"Hello\",))\n```\n\n\n### CheckBox\nThe CheckBox item is a bit more complex than a regular button, it has 2 differents callbacks instead of 1 and different arguments for each, one for when the checkbox switch from the 'Disabled' to 'Enabled' state (Not checked to checked), and one for when it switch from the 'Enabled' to 'Disabled' state (Checked to not checked).\n\nYou can 'Disable' the interactions with your checkbox by setting the value of `check_default` to `None`.\n\n> [!NOTE]\n> The callback won't be executed if the user clicks on the checkbox when it is disabled.\n\nTo create one, use the `tray_manager.CheckBox` class as followed :\n\n```python\nfrom tray_manager import CheckBox\n\ndef checked(text: str) -> None:\n print(f\"In procedure 'checked' : {text}\")\n\ndef unchecked(text: str) -> None:\n print(f\"In procedure 'unchecked' : {text}\")\n\nmy_checkbox = CheckBox(\"My CheckBox\", check_default=False, checked_callback=checked, checked_callback_args=(\"I'm now checked\",),\n unchecked_callback=unchecked, unchecked_callback_args=(\"I'm now unchecked\",))\n```\n\nTo get the current state of the checkbox, you can use the `.get_status()` function as followed :\n\n```python\nfrom tray_manager import CheckBox\n\nmy_checkbox = CheckBox(\"My CheckBox\")\n\nmy_checkbox.get_status()\n-> bool | None\n```\n\nYou can also set the state of the checkbox by using the `.set_status()` function as followed : \n\n```python\nfrom tray_manager import CheckBox\n\nmy_checkbox = CheckBox(\"My CheckBox\")\n\nmy_checkbox.set_status(True)\n-> Checked\nmy_checkbox.set_status(False)\n-> Unchecked\nmy_checkbox.set_status(None)\n-> Disabled\n```\n\n> [!NOTE]\n>\n> | Checkbox | Status |\n> | :---: | :---: |\n> | Checked | `True` | \n> | Unchecked | `False` |\n> | Disabled | `None` |\n>\n> When the checkbox is disabled, it stays in it's previous state and stop interacting, this means that if the checkbox was checked before being disabled, the checkbox will stay checked but nothing will happen if the user click on it.\n\n\n### Separator\nThe separator is a built-in object of Pystray, it doesn't have any parameters.\n\nTo create one, use the `tray_manager.Separator` class as followed : \n\n```python\nfrom tray_manager import Separator\nmy_separator = Separator()\n```\n\n### Submenu\nThe submenu is like a `tray_manager.Menu` object and can contains other items including other submenu.\n\n> [!CAUTION]\n> Be carreful when adding submenu into each others as adding a submenu to a submenu that is contained in the submenu you're adding will generate a `tray_manager.CircularAddException` error.\n> ```mermaid\n> flowchart TD\n> A{My Submenu} --> B(My Label)\n> A --> C(My Button)\n> A --> D{My Second Submenu}\n> D --> E(My Second Label)\n> D --> F(My Checkbox)\n> D --> |\u274c tray_manager.CircularAddException| A\n> ```\n\n\nTo create one, use the `tray_manager.Submenu` as followed : \n\n```python\nfrom tray_manager import Submenu\nmy_submenu = Submenu(\"My Submenu\")\n```\n\nTo add an item to the submenu, use the `.add()` function as followed : \n\n```python\nfrom tray_manager import Submenu, Label\nmy_submenu = Submenu(\"My Submenu\")\nmy_label = Label(\"My Label\")\n\nmy_submenu.add(my_label)\n```\nTo remove an item from the submenu, use the `.remove()` function as followed :\n\n```python\nfrom tray_manager import Submenu, Label\nmy_submenu = Submenu(\"My Submenu\")\nmy_label = Label(\"My Label\")\n\nmy_submenu.add(my_label)\n\nmy_submenu.remove(my_label)\n-> my_label\n```\n> [!NOTE]\n> The `.remove()` function return the item that was removed\n\n\nTo get the items contained in a submenu, use the `.get_items()` function as followed:\n\n```python\nfrom tray_manager import Submenu, Label, Button\n\ndef my_callback()\n print(\"Hello\")\n\nmy_submenu = Submenu(\"My Submenu\")\nmy_label = Label(\"My Label\")\nmy_button = Button(\"My Button\", my_callback)\n\nmy_submenu.add(my_label)\nmy_submenu.add(my_button)\n\nmy_submenu.get_items()\n-> [my_label, my_button]\n```\n\n## Add the items to the Menu\nThe `tray_manager.Menu` is one of the central elements of this library, it works like a submenu and is created automatically when you create a `tray_manager.TrayManager` object as the `tray_manager.TrayManager.menu` object and cannot be removed.\n\n> [!WARNING]\n> Check `tray_manager.OsSupport.HAS_MENU` for disponibility on your OS, if your OS doesn't support the menu, the `tray_manager.TrayManager.menu` object will be None.\n\nTo use the menu, acces the `tray_manager.TrayManager.menu` object as followed : \n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\nmy_menu = my_tray.menu\n```\n\nTo add an item to the menu, use the `.add()` function as followed : \n\n```python\nfrom tray_manager import TrayManager, Label\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\nmy_menu = my_tray.menu\n\nmy_label = Label(\"My Label\")\n\nmy_menu.add(my_label)\n```\n\nTo remove an item from the menu, you can use the `.remove()` function as followed : \n\n```python\nfrom tray_manager import TrayManager, Label\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\nmy_menu = my_tray.menu\n\nmy_label = Label(\"My Label\")\nmy_menu.add(my_label)\n\nmy_menu.remove(my_label)\n-> my_label\n```\n\n> [!NOTE]\n> The `.remove()` function return the item that was removed.\n\nTo get the items contained in a menu, you can use the `.get_items()` function as followed:\n\n```python\nfrom tray_manager import TrayManager, Menu, Label, Button\n\ndef my_callback()\n print(\"Hello\")\n\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\nmy_menu = my_tray.menu\n\nmy_label = Label(\"My Label\")\nmy_button = Button(\"My Button\", my_callback)\n\nmy_menu.add(my_label)\nmy_menu.add(my_button)\n\nmy_menu.get_items()\n-> [my_label, my_button]\n```\n\nTo update the menu items (The items contained inside the menu), use the `.update()` function.\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\nmy_menu = my_tray.menu\n\nmy_menu.update()\n```\n> [!NOTE]\n> The `.update()` function is triggered automatically every time you edit, add or remove an item from the menu.\n\n## Customize the TrayManager object\nYou can customize your TrayManager object in different ways such as :\n\n1. [Setting a new name for the app](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-a-new-name-for-the-app)\n2. [Setting a new icon for the app](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-a-new-icon-for-the-app)\n3. [Hiding / Showing the app in the system tray](https://github.com/Adastram1/tray_manager/blob/main/README.md#hiding--showing-the-app-in-the-system-tray)\n\n### Setting a new name for the app\nTo set a new name for your app use the `.set_app_name()` function as followed :\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\n\nmy_tray.set_app_name(\"My new App\")\n```\n### Setting a new icon for the app\n`tray_manager` use a memory system for icons, to set a new icon for your app, you first need to load it using the `.load_icon()` function, then set the icon as the new icon using the `.set_icon()` function of the `tray_manager.TrayManager` object.\n\n> [!NOTE]\n> By default, the icon is a white square of 32x32 pixels.\n> The default icon is always loaded in memory and can be set again by passing the `tray_manager.Values.DEFAULT` as the `name` argument of the `.set_icon()` function.\n\n\nTo load an icon, use the `.load_icon()` function and pass it **a file path, a encoded image, a `PIL.Image` object or any file that can be read and interpreted as an image by PIL**. You also need to pass a name that will be used as a key in the icons dictionnary to retreive your icon.\n\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\n\nmy_tray.load_icon(\"my_icon_file_path.png\", \"my_new_icon\")\n```\n> [!WARNING]\n> `tray_manager` use a dictionnary to save your loaded icons, this means that loading an image using a name that was already used will overwrite the image that was previously loaded with that name.\n> The only exception to this is the default icon that cannot be edited.\n\nTo set an icon, use the `.set_icon()` function and pass it the name (key) of your icon that you set when you loaded the icon.\n\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\n\nmy_tray.load_icon(\"my_icon_file_path.png\", \"my_new_icon\")\nmy_tray.set_icon(\"my_new_icon\")\n```\n\n### Hiding / Showing the app in the system tray\nInstead of killing the `tray_manager.TrayManager` object when you want it to stop being displayed in the system tray and creating a new one once you need it again, you can use the `.show()` and `.hide()` functions of the the `tray_manager.TrayManager` object to control whether the app is visible in the system tray or not. \n\n> [!NOTE]\n> You can set the `default_show` argument of the `tray_manager.TrayManager` object to `True` or `False` when creating your `tray_manager.TrayManager` object to define whether the system tray icon will be displayed or not once the object is created.\n\nTo show the app in the system tray, use the `.show()` function of the the `tray_manager.TrayManager` object as followed : \n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\n\nmy_tray.show()\n```\n\nTo hide the app in the system tray, use the `.hide()` function of the the `tray_manager.TrayManager` object as followed :\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_seperate_thread=True)\n\nmy_tray.hide()\n```\n\n## Customize and edit the items\nTo edit an already created item, use the `.edit()` function of the item, when doing so, you only need to specify which arguments you want to change, and the others will stay the same as they were.\n\nTo edit an item, do as followed : \n```python\nfrom tray_manager import Button\n\ndef my_first_callback():\n print(\"Hello\")\n my_button.edit(callback=my_second_callback)\n\ndef my_second_callback():\n print(\"World !\")\n\nmy_button = Button(\"My Button\", my_first_callback)\n\n# When clicking on the button, this will display :\n# First click\n-> Hello\n# Second click\n-> World !\n```\n\nYou can custom the items in different ways such as : \n\n1. [Enabling / Disabling the item (Gray look and non-responsive)](https://github.com/Adastram1/tray_manager/blob/main/README.md#enabling--disabling-the-item-gray-look-and-non-responsive)\n2. [Setting the default attribut to the item (Bold look)](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-the-default-attribut-to-the-item-bold-look)\n3. [Setting the radio look on the checkbox (A dot instead of a crossmark)](https://github.com/Adastram1/tray_manager/blob/main/README.md#setting-the-radio-look-on-the-checkbox-a-dot-instead-of-a-crossmark)\n\n### Enabling / Disabling the item (Gray look and non-responsive)\nIf you want to display the item but you want it to be non-responsive (for Button, CheckBox and Submenu) and look like a disabled item, you can use the `.enable()` and `.disable()` functions of the item.\n\n> [!NOTE]\n> By default, every items are enabled\n> \n> Every item can be disabled except the separator.\n\nTo enable your item, use the `.enable()` function of the item as followed : \n```python\nfrom tray_manager import CheckBox\n\ndef checked_callback():\n print(\"Checked\")\n\ndef unchecked_callback():\n print(\"Unchecked\")\n\nmy_checkbox = CheckBox(\"My CheckBox\", checked_callback=checked_callback, unchecked_callback=unchecked_callback)\n\nmy_checkbox.enable()\n```\n\nTo disable your item, use the `.disable()` function of the item as followed : \n```python\nfrom tray_manager import CheckBox\n\ndef checked_callback():\n print(\"Checked\")\n\ndef unchecked_callback():\n print(\"Unchecked\")\n\nmy_checkbox = CheckBox(\"My CheckBox\", checked_callback=checked_callback, unchecked_callback=unchecked_callback)\n\nmy_checkbox.disable()\n```\n\n### Setting the default attribut to the item (Bold look)\nTo make your item the default item of the menu / submenu and give it a bold look, you can set the `default` attribut when creating / editing the item to `True`. \n\n> [!NOTE]\n> You can only have 1 default item by menu / submenu. By default, there is no default item.\n\nTo set the `default` attribut of the item, do as followed : \n\nWhen creating the item : \n```python\nfrom tray_manager import Label\nmy_label = Label(\"My Label\", default=True)\n```\n\nWhen editing the item : \n```python\nfrom tray_manager import Label\nmy_label = Label(\"My Label\")\nmy_label.edit(default=True)\n```\n\n### Setting the radio look on the checkbox (A dot instead of a crossmark)\nIf you want to give a new look to your regular checkbox crossmark, you can set the `use_radio_look` attribut of the CheckBox to `True` when creating / editing the CheckBox.\n\nTo set the `use_radio_look` attribut of the item, do as followed : \n\nWhen creating the item : \n```python\nfrom tray_manager import CheckBox\n\ndef checked_callback():\n print(\"Checked\")\n\ndef unchecked_callback():\n print(\"Unchecked\")\n\nmy_checkbox = CheckBox(\"My CheckBox\", checked_callback=checked_callback, unchecked_callback=unchecked_callback, use_radio_look=True)\n```\n\nWhen editing the item : \n```python\nfrom tray_manager import CheckBox\n\ndef checked_callback():\n print(\"Checked\")\n\ndef unchecked_callback():\n print(\"Unchecked\")\n\nmy_checkbox = CheckBox(\"My CheckBox\", checked_callback=checked_callback, unchecked_callback=unchecked_callback)\nmy_checkbox.edit(use_radio_look=True)\n```\n\n## Check for OS supported features\nBefore using features of the `tray_manager package`, you **must** check if they are compatible with your OS. To do so, use the `tray_manager.Os_Support` object.\nThere is 4 differents features that you need to check before using : \n1. Os_Support.SUPPORT_MENU\n2. Os_Support.SUPPORT_DEFAULT\n3. Os_Support.SUPPORT_RADIO\n4. Os_Support.SUPPORT_NOTIFICATION [CURRENTLY UNAVAILBE]\n\nTo know if your OS support a feature the corresponding `Os_Support` variable must be True.\n\nExample, to check if your OS support the menu, do as followed : \n```python\nfrom tray_manager import Os_Support\nif Os_Support.SUPPORT_MENU:\n print(\"The menu is supported by your OS\")\nelse:\n print(\"The menu isn't supported by your OS\")\n```\n\n> [!NOTE]\n> Here is a chart of the features that are ***supposed*** and ***not supposed*** to be supported by each OS and backends.\n> | Feature \\ OS and backend | Windows (win32) | Linux (gtk) | Linux (appindicator) | Linux (ayatana-appindicator) | Linux (xorg) | MacOS (darwin) |\n> | :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n> | Menu | Supported | Supported | Supported | Supported | Not Supported | Supported |\n> | Default | Supported | Supported | Not Supported | Not Supported | Supported | Not Supported |\n> | Radio | Supported | Supported | Supported | Supported | Supported | Not Supported |\n> | Notification | Currently Unavailbe | Unknown | Uknown | Unknown | Not Supported | Not Supported |\n\n## Notifications [CURRENTLY UNAVAIBLE]\nIf you want to create a notification on the user's screen, you can use the `tray_manager.TrayManager.notification` object.\n\nTo create a notification, use the `.notify()` function of the `tray_manager.TrayManager.notification` object as followed :\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_separate_thread=True)\nnotification = my_tray.notification\n\nnotification.notify(\"My App\", \"Hello World !\")\n```\n\nYou can specify a delay after which the notification will be removed by passing a value **in seconds** to the `.notify()` function as the `remove_after_s` as followed :\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_separate_thread=True)\nnotification = my_tray.notification\n\nnotification.notify(\"My App\", \"Hello World !\", remove_after_s=10)\n# The notification will close by itself after 10 seconds\n```\n\nYou can also use the `.remove_notification()` function to manually remove the notification as followed :\n```python\nfrom tray_manager import TrayManager\nmy_tray = TrayManager(\"My App\", run_in_separate_thread=True)\nnotification = my_tray.notification\n\nnotification.notify(\"My App\", \"Hello World !)\n\n# Some code here\n\nnotification.remove_notification()\n```\n\n> [!CAUTION]\n> By default the notification will **never** close by itself, make sure to close it before creating a new one.\n\n## Advanced settings\n### Selecting a backend\nIf you need specific features, you can set the `backend` argument of the `tray_manager.TrayManager` object to one of the `tray_manager.Backends` values.\n\n> [!NOTE]\n> By default pystray will use the best backend avaible on your os.\n\n> [!CAUTION]\n> You **MUST** use the backend from the `tray_manager.Backends` class, passing the value of one of the object of the class will raise an error.\n>\n> You **MUST** also use a backend compatible with you OS. \n> \n> | OS | Backends |\n> | :---: | :---: |\n> | Windows | `win32` |\n> | MacOS | `darwin` |\n> | Linux | `gtk`, `appindicator`, `ayatana-appindicator`, `xorg` | \n",
"bugtrack_url": null,
"license": "GNU Lesser General Public License v3 (LGPLv3)",
"summary": "An \"easier\" version to use of the pystray librairy (https://github.com/moses-palmer/pystray by Moses Palm\u00e9r)",
"version": "1.0.3",
"project_urls": {
"Homepage": "https://github.com/Adastram1/tray_manager"
},
"split_keywords": [
"python",
" manager",
" system tray",
" pystray"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8d21e147d6752059eb4575463f19bfb20b3576b35cf9223e299256cdbdbafe00",
"md5": "fae3ee5cb9a6f74015412e67e113de75",
"sha256": "466972de586f24449342615d615b022dd48c234ba54c1ec6650dc9d7d1a5ac1d"
},
"downloads": -1,
"filename": "tray_manager-1.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fae3ee5cb9a6f74015412e67e113de75",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 29786,
"upload_time": "2024-06-06T09:35:38",
"upload_time_iso_8601": "2024-06-06T09:35:38.942169Z",
"url": "https://files.pythonhosted.org/packages/8d/21/e147d6752059eb4575463f19bfb20b3576b35cf9223e299256cdbdbafe00/tray_manager-1.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a52137ea4e3e02c561d68ab655b975445490d0bc6da93fc9d15bebdc15ee0092",
"md5": "9c606efd6d7901a397bc9dad48bc5e11",
"sha256": "b3b7bd5c5e76332c2aa5a621cc8a0c31bc0308792715b9bb9d99a1bc5baa681c"
},
"downloads": -1,
"filename": "tray_manager-1.0.3.tar.gz",
"has_sig": false,
"md5_digest": "9c606efd6d7901a397bc9dad48bc5e11",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 34049,
"upload_time": "2024-06-06T09:35:43",
"upload_time_iso_8601": "2024-06-06T09:35:43.615397Z",
"url": "https://files.pythonhosted.org/packages/a5/21/37ea4e3e02c561d68ab655b975445490d0bc6da93fc9d15bebdc15ee0092/tray_manager-1.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-06 09:35:43",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Adastram1",
"github_project": "tray_manager",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pystray",
"specs": [
[
"==",
"0.19.5"
]
]
},
{
"name": "pillow",
"specs": [
[
"==",
"10.2.0"
]
]
}
],
"lcname": "tray-manager"
}