【问题标题】:How to create a system tray popup message with python? (Windows)如何使用python创建系统托盘弹出消息? (视窗)
【发布时间】:2013-04-02 00:29:03
【问题描述】:

我想知道如何使用 python 创建系统托盘弹出消息。我已经在很多软件中看到了这些,但很难找到资源来轻松使用任何语言进行操作。任何人都知道一些在 Python 中执行此操作的库?

【问题讨论】:

    标签: python notifications popup system-tray


    【解决方案1】:

    pywin32 library 的帮助下,您可以使用我找到的以下示例代码here

    from win32api import *
    from win32gui import *
    import win32con
    import sys, os
    import struct
    import time
    
    class WindowsBalloonTip:
        def __init__(self, title, msg):
            message_map = {
                    win32con.WM_DESTROY: self.OnDestroy,
            }
            # Register the Window class.
            wc = WNDCLASS()
            hinst = wc.hInstance = GetModuleHandle(None)
            wc.lpszClassName = "PythonTaskbar"
            wc.lpfnWndProc = message_map # could also specify a wndproc.
            classAtom = RegisterClass(wc)
            # Create the Window.
            style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
            self.hwnd = CreateWindow( classAtom, "Taskbar", style, \
                    0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
                    0, 0, hinst, None)
            UpdateWindow(self.hwnd)
            iconPathName = os.path.abspath(os.path.join( sys.path[0], "balloontip.ico" ))
            icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
            try:
               hicon = LoadImage(hinst, iconPathName, \
                        win32con.IMAGE_ICON, 0, 0, icon_flags)
            except:
              hicon = LoadIcon(0, win32con.IDI_APPLICATION)
            flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
            nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "tooltip")
            Shell_NotifyIcon(NIM_ADD, nid)
            Shell_NotifyIcon(NIM_MODIFY, \
                             (self.hwnd, 0, NIF_INFO, win32con.WM_USER+20,\
                              hicon, "Balloon  tooltip",msg,200,title))
            # self.show_balloon(title, msg)
            time.sleep(10)
            DestroyWindow(self.hwnd)
        def OnDestroy(self, hwnd, msg, wparam, lparam):
            nid = (self.hwnd, 0)
            Shell_NotifyIcon(NIM_DELETE, nid)
            PostQuitMessage(0) # Terminate the app.
    
    def balloon_tip(title, msg):
        w=WindowsBalloonTip(title, msg)
    
    if __name__ == '__main__':
        balloon_tip("Title for popup", "This is the popup's message")
    

    【讨论】:

    • 工作,但我希望它更“现代”,不同的外观和感觉。例如,能够将图像添加到弹出窗口中。这种方法可以吗?
    • 没试过,但也许用图标的路径代替 iconPathName 可能会起作用
    • 这有效,但前提是您为lpszClassName 分配一个随机类名。如果您按原样运行该示例,它将仅显示一个气泡帮助,然后在下一次尝试失败并显示pywintypes.error: (1410, 'RegisterClass', 'Class already exists')。作为快速破解,我使用了from uuid import uuid4 并在名称中添加了uuid4()
    • 我是编程新手,如何将其链接到我的 GUI 脚本?基本测试有效,但我很难看到一个功能,双击系统托盘图标,将打开程序。我也尝试使用pythonw打开它,但它仍然作为普通的任务栏应用程序打开。
    【解决方案2】:

    我最近使用Plyer 包创建了跨平台通知,使用Notification 外观(它还有许多其他有趣的东西值得一看)。

    很容易使用:

    from plyer.utils import platform
    from plyer import notification
    
    notification.notify(
        title='Here is the title',
        message='Here is the message',
        app_name='Here is the application name',
        app_icon='path/to/the/icon.' + ('ico' if platform == 'win' else 'png')
    )
    

    【讨论】:

    • 当我使用这个库时,我收到了来自python27_x64\lib\site-packages\plyer\platforms\win\libs\balloontip.py", line 145, in balloon_tip 的错误,方法为WindowsBalloonTip(**kwargs),错误消息是:TypeError: __init__() got an unexpected keyword argument 'ticker'。它是带有 python 2.7 的 windows7。
    • ... 并检查 repo,已经发布了类似的问题,作者建议直接从 Github 安装最新的开发版本,这样就解决了问题。伟大的! pip install -I https://github.com/kivy/plyer/zipball/master
    • 遇到了一个问题,在多次运行我的应用程序后,我的通知运行没有任何问题,但是,后来它开始抛出异常 [异常:Shell_NotifyIconW 失败。 ]
    • 根据plyer notification.notifiy函数实现中的cmets,在Windows上调用app_icon需要为.ICO格式(而不是.png)。
    • @Thijs 是的,文档中也提到了:plyer.readthedocs.io/en/latest/#plyer.facades.Notification。更新了我的示例脚本。
    【解决方案3】:

    这是使用 python 在 Windows 10 上显示通知的简单方法:模块 win10toast

    要求

    • pypiwin32
    • 设置工具

    安装

    >> pip install win10toast
    

    示例

    from win10toast import ToastNotifier
    toaster = ToastNotifier()
    toaster.show_toast("Demo notification",
                       "Hello world",
                       duration=10)
    

    【讨论】:

    • 这个模块支持win8/7吗?
    • @ExillustX 我没有在 win8/7 上尝试过我认为 PyQt5 包在 win8/7 上提供了类似的行为。请检查一次。
    • 我们能给出一个应该弹出的时间吗?我们还可以将所有通知保存在一个地方吗?比如可能是一个文件?
    • 这让我的程序崩溃了。
    • @ExillustX 我在 Windows 7 上运行它,它运行良好。但它与 Windows 10 通知不同
    【解决方案4】:

    您将需要使用第 3 方 python GUI 库或 pywin32 库。 TkInter,python自带的GUI工具包,不支持系统托盘弹出。

    支持使用系统托盘的多种中性库:

    • wxPython
    • PyGTK
    • PyQT

    支持使用系统托盘的 Windows 特定库:

    • pywin32

    在 windows 上使用 wxpython 弹出系统托盘的信息/示例:

    【讨论】:

    【解决方案5】:

    Windows

    现在有一种使用Python/Winrt 的官方方法来实现这一点,github 解释了如何将 UWP API 映射到 python 的。

    通过关注official UWP documentation,我设法显示了一个小通知,该通知也出现在 Windows 通知中心:

    import winrt.windows.ui.notifications as notifications
    import winrt.windows.data.xml.dom as dom
    
    #create notifier
    nManager = notifications.ToastNotificationManager
    notifier = nManager.create_toast_notifier();
    
    #define your notification as string
    tString = """
    <toast>
        <visual>
            <binding template='ToastGeneric'>
                <text>Sample toast</text>
                <text>Sample content</text>
            </binding>
        </visual>
    </toast>
    """
    
    #convert notification to an XmlDocument
    xDoc = dom.XmlDocument()
    xDoc.load_xml(tString)
    
    #display notification
    notifier.show(notifications.ToastNotification(xDoc))
    

    设置仅限于库的安装

    pip install winrt
    

    要求

    Windows 10,2018 年 10 月更新或更高版本

    适用于 Windows 的 Python,版本 3.7 或更高版本

    pip,版本 19 或更高版本

    奖励 macOS

    我还找到了一种在 macOS 中使用 AppleScript 的方法,以下代码的目标是构建将通过 python os.system 执行的 AppleScript 代码

    import os
    
    def displayNotification(message,title=None,subtitle=None,soundname=None):
        """
            Display an OSX notification with message title an subtitle
            sounds are located in /System/Library/Sounds or ~/Library/Sounds
        """
        titlePart = ''
        if(not title is None):
            titlePart = 'with title "{0}"'.format(title)
        subtitlePart = ''
        if(not subtitle is None):
            subtitlePart = 'subtitle "{0}"'.format(subtitle)
        soundnamePart = ''
        if(not soundname is None):
            soundnamePart = 'sound name "{0}"'.format(soundname)
    
        appleScriptNotification = 'display notification "{0}" {1} {2} {3}'.format(message,titlePart,subtitlePart,soundnamePart)
        os.system("osascript -e '{0}'".format(appleScriptNotification))
    

    使用 asis :

    displayNotification("message","title","subtitle","Pop")
    

    结语

    我把前面所有的代码总结成两个要点

    Windows

    macOS

    【讨论】:

    • 来自微软的爱?
    • notifier = nManager.create_toast_notifier() # 引发异常 Traceback (最近一次调用最后一次): File "", line 1, in RuntimeError: Element not found.
    • 确实,最近的 windows 更新(或 API/配置更改)似乎破坏了此代码。 (其他开发人员在我的要点的评论部分报告了相同的行为)
    • 有什么方法可以将 toast 通知的按钮连接到一个动作?或者有什么方法可以获取 toast 通知的输入?
    【解决方案6】:

    在Linux系统中,你可以使用内置命令notify-send

    ntfy 库可用于发送推送通知。

    click here for ntfy documentation

    安装:

    sudo pip install ntfy
    

    例子:

    ntfy send "your message!"
    ntfy -t "your custom title" send "your message"
    

    【讨论】:

    • 我要补充一点,这是一个从命令行调用的 Python 程序,而不是一个内部 Python 命令
    【解决方案7】:

    最简单的方法是使用win10toast

    这是代码:

    from win10toast import ToastNotifier
    
    Notifi = ToastNotifier()  
    Notifi.show_toast("Title", "Description")
    

    这可能会对你有所帮助!

    【讨论】:

    • 与 Ananth Kumar Vasamsetti 的回答相比,这如何提供新的价值?
    猜你喜欢
    • 2011-02-20
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2018-03-07
    • 2017-02-03
    • 1970-01-01
    相关资源
    最近更新 更多