0

I want to create application with taskbar/system-tray icon. Crossplatform. OSX, Windows, Linux (Ubuntu/Centos/Mint/Manjaro and other popular distros).

This app should detect keyboard input and react to it. Basically do some actions on specific keys. Example: user wants to play some music, presses shift+ctrl+p. Music starts playing.

I know that Kivy capable of detecting

idchlife
  • 554
  • 1
  • 6
  • 16
  • Does this help you? https://stackoverflow.com/questions/17280341/how-do-you-check-for-keyboard-events-with-kivy – jda5 Apr 12 '21 at 12:50
  • @jda5 basically - no, because events are tracked only when window is focused. but thanks for the effort! – idchlife Apr 13 '21 at 09:41

3 Answers3

0

For the "cross-platform system-tray" thingy - I don't think this is entirely possible without some truly cross-platform framework like Elektron or something, which can give ability to use system-tray/taskbar feature.

For the detecting mouse even when window is not focused - use pynput with asyncio (example for kivy + asyncio in their official repository). Basically: you can detect keyboard events even when app is not focused with background working code with asyncio. Then it will detect every keystroke.

idchlife
  • 554
  • 1
  • 6
  • 16
0
import PySimpleGUI as sg
from psgtray import SystemTray

"""
    A System Tray Icon courtesy of pystray and your friends at PySimpleGUI

    Import the SystemTray object with this line of code:
    from psgtray import SystemTray

    Key for the system tray icon is: 
        tray = SystemTray()
        tray.key

    values[key] contains the menu item chosen.

    One trick employed here is to change the window's event to be the event from the System Tray.


    Copyright PySimpleGUI 2021
"""


def main():
    menu = ['',
            ['Show Window', 'Hide Window', '---', '!Disabled Item', 'Change Icon', ['Happy', 'Sad', 'Plain'], 'Exit']]
    tooltip = 'Tooltip'

    layout = [[sg.Text('My PySimpleGUI Celebration Window - X will minimize to tray')],
              [sg.T('Double clip icon to restore or right click and choose Show Window')],
              [sg.T('Icon Tooltip:'), sg.Input(tooltip, key='-IN-', s=(20, 1)), sg.B('Change Tooltip')],
              [sg.Multiline(size=(60, 10), reroute_stdout=False, reroute_cprint=True, write_only=True, key='-OUT-')],
              [sg.Button('Go'), sg.B('Hide Icon'), sg.B('Show Icon'), sg.B('Hide Window'), sg.Button('Exit')]]

    window = sg.Window('Window Title', layout, finalize=True, enable_close_attempted_event=True)

    tray = SystemTray(menu, single_click_events=False, window=window, tooltip=tooltip, icon='cogent_logo.png')
    tray.show_message('System Tray', 'System Tray Icon Started!')
    sg.cprint(sg.get_versions())
    while True:
        event, values = window.read()

        # IMPORTANT step. It's not required, but convenient. Set event to value from tray
        # if it's a tray event, change the event variable to be whatever the tray sent
        if event == tray.key:
            sg.cprint(f'System Tray Event = ', values[event], c='white on red')
            event = values[event]  # use the System Tray's event as if was from the window

        if event in (sg.WIN_CLOSED, 'Exit'):
            break

        sg.cprint(event, values)
        tray.show_message(title=event, message=values)

        if event in ('Show Window', sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED):
            window.un_hide()
            window.bring_to_front()
        elif event in ('Hide Window', sg.WIN_CLOSE_ATTEMPTED_EVENT):
            window.hide()
            tray.show_icon()  # if hiding window, better make sure the icon is visible
            # tray.notify('System Tray Item Chosen', f'You chose {event}')
        elif event == 'Happy':
            tray.change_icon(sg.EMOJI_BASE64_HAPPY_JOY)
        elif event == 'Sad':
            tray.change_icon(sg.EMOJI_BASE64_FRUSTRATED)
        elif event == 'Plain':
            tray.change_icon(sg.DEFAULT_BASE64_ICON)
        elif event == 'Hide Icon':
            tray.hide_icon()
        elif event == 'Show Icon':
            tray.show_icon()
        elif event == 'Change Tooltip':
            tray.set_tooltip(values['-IN-'])

    tray.close()  # optional but without a close, the icon may "linger" until moused over
    window.close()


if __name__ == '__main__':
    main()
Jason Yang
  • 11,284
  • 2
  • 9
  • 23
sarim ali
  • 9
  • 3
  • This looks like code copied from https://github.com/PySimpleGUI/psgtray - please do not do that without proper attribution. Also, please explain how this code resolves the given problem. A good explanation helps others to learn from your answer – Nico Haase Mar 03 '22 at 08:09
0

If you're willing to depart from Kivy and use another framework, PySimpleGUI has a System Tray capability (at least for Windows, and perhaps Linux/Mac) when running the tkinter version. The PySimpleGUIQt port has a more "official" System Tray feature.

The GitHub Repo PySimpleHotkey is one example of how to use the psgtray package to make a hotkey program.

https://github.com/PySimpleGUI/PySimpleHotkey

Mike from PSG
  • 5,312
  • 21
  • 39