如何使用系统托盘/任务栏图标制作跨平台 Kivy 应用程序,即使应用程序没有聚焦/处于任务栏模式,它也会检测键盘输入

Posted

技术标签:

【中文标题】如何使用系统托盘/任务栏图标制作跨平台 Kivy 应用程序,即使应用程序没有聚焦/处于任务栏模式,它也会检测键盘输入【英文标题】:How can I make cross-platform Kivy app with system-tray/taskbar icon which would detect keyboard input even when app is not focused/in taskbar mode 【发布时间】:2021-07-06 06:28:39 【问题描述】:

我想创建带有任务栏/系统托盘图标的应用程序。跨平台。 OSX、Windows、Linux(Ubuntu/Centos/Mint/Manjaro 和其他流行的发行版)。

此应用应检测键盘输入并对其做出反应。基本上对特定键做一些操作。示例:用户想要播放一些音乐,按 shift+ctrl+p。音乐开始播放。

我知道 Kivy 能够检测到

【问题讨论】:

这对您有帮助吗? ***.com/questions/17280341/… @jda5 基本上 - 不,因为只有在聚焦窗口时才会跟踪事件。但感谢您的努力! 【参考方案1】:

对于“跨平台系统托盘”的东西 - 我认为如果没有像 Elektron 之类的真正跨平台框架,它可以提供使用系统托盘/任务栏功能的能力,这是完全可能的。

即使在窗口没有聚焦时也能检测鼠标 - 使用带有 asyncio 的 pynput(例如,kivy + asyncio 在他们的官方存储库中)。基本上:即使应用程序没有关注使用 asyncio 的后台工作代码,您也可以检测到键盘事件。然后它会检测每一次击键。

【讨论】:

【参考方案2】:
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()

【讨论】:

这看起来像是从github.com/PySimpleGUI/psgtray 复制的代码 - 请不要在没有适当归属的情况下这样做。另外,请解释此代码如何解决给定问题。一个好的解释可以帮助其他人从你的答案中学习【参考方案3】:

如果您愿意离开 Kivy 并使用另一个框架,PySimpleGUI 在运行 tkinter 版本时具有系统托盘功能(至少适用于 Windows,可能还有 Linux/Mac)。 PySimpleGUIQt 移植版具有更“官方”的系统托盘功能。

GitHub Repo PySimpleHotkey 是如何使用 psgtray 包制作热键程序的一个示例。

https://github.com/PySimpleGUI/PySimpleHotkey

【讨论】:

以上是关于如何使用系统托盘/任务栏图标制作跨平台 Kivy 应用程序,即使应用程序没有聚焦/处于任务栏模式,它也会检测键盘输入的主要内容,如果未能解决你的问题,请参考以下文章

如何在任务栏中将图标设置为 kivy 应用程序?

Qt开发实现系统托盘,托盘菜单,托盘消息

实现系统托盘

WinForm 之 窗口最小化到托盘及右键图标显示菜单

怎样让VB编写的程序打开后不在任务栏显示

Qt设置系统托盘图标和程序图标