48

I'd like to know how to create a system tray popup message with python. I have seen those in lots of softaware, but yet difficult to find resources to do it easily with any language. Anyone knows some library for doing this in Python?

dreftymac
  • 31,404
  • 26
  • 119
  • 182
Roman Rdgz
  • 12,836
  • 41
  • 131
  • 207

7 Answers7

55

With the help of the pywin32 library you can use the following example code I found 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")
halex
  • 16,253
  • 5
  • 58
  • 67
  • Works, but I'd like it to be more "modern", different look&feel. Being able to add an image into the popup for example. Is that possible with this apprach? – Roman Rdgz Apr 10 '13 at 09:58
  • 1
    haven't tried, but maybe giving the path to icon in place of the iconPathName might work – otaku Dec 07 '16 at 07:24
  • 2
    This works, but only if you assign a random classname to `lpszClassName`. If you run the example as is, it will only display one bubble help and then on the next try fail with `pywintypes.error: (1410, 'RegisterClass', 'Class already exists')`. As a quick hack, I used `from uuid import uuid4` and added `uuid4()` to the name. – 576i Mar 30 '20 at 09:00
  • I'm a newbie in programming, how do I link this to my GUI script? The basic test works, but I am struggling to see a function which, upon double-click on the system tray icon, will open the programme. I also tried to open it using pythonw, but it is still opening as a normal taskbar application. – ISquared Jul 31 '20 at 08:44
41

I recently used the Plyer package to create cross-platform notifications without pain, using the Notification facade (it have many other interesting things that are worth to take a look at).

Pretty easy to use:

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.{}'.format(
        # On Windows, app_icon has to be a path to a file in .ICO format.
        'ico' if platform == 'win' else 'png'
    )
)
Epoc
  • 7,208
  • 8
  • 62
  • 66
  • 1
    When I use this lib, I got an error from `python27_x64\lib\site-packages\plyer\platforms\win\libs\balloontip.py", line 145, in balloon_tip`, of method `WindowsBalloonTip(**kwargs)`, the error message is: `TypeError: __init__() got an unexpected keyword argument 'ticker'`. It is windows7 with python 2.7. – WesternGun Jan 08 '18 at 10:14
  • 3
    ... and checking the repo, a similar issue is posted already and the author suggests to install the latest dev release directly from Github, and that solves the problem. Great! `pip install -I https://github.com/kivy/plyer/zipball/master` – WesternGun Jan 08 '18 at 10:24
  • 1
    Got an issue, after running the my app several times I got the notifications running without any problem, however, later on it started throwing exception [ Exception: Shell_NotifyIconW failed. ] – alex_z Mar 05 '19 at 14:10
  • According to comments in plyer notification.notifiy function implementation, the app_icon needs to be in .ICO format when called on Windows (instead of .png). – Thijs Jul 28 '20 at 13:46
  • @Thijs Yes, it's mentioned in the docs as well: https://plyer.readthedocs.io/en/latest/#plyer.facades.Notification. Updated my example script. – Epoc Aug 03 '20 at 09:40
20

Here is the simple way to show notifications on windows 10 using python: module win10toast.

Requirements:

  • pypiwin32
  • setuptools

Installation:

>> pip install win10toast

Example:

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

Resultant of the code

Jean-Francois T.
  • 11,549
  • 7
  • 68
  • 107
9

Windows

There's now an official way to achieve that using Python/Winrt, the github explains how to map UWP API to python ones.

By following the official UWP documentation I've managed to display a small notification that also appears in Windows notification center :

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))

The setup is limited to the installation of the library

pip install winrt

Requirements

Windows 10, October 2018 Update or later

Python for Windows, version 3.7 or later

pip, version 19 or later

Bonus macOS

I've also found a way to do it in macOS by using AppleScript, the goal of the following code is to build an AppleScript code that will be executed via python os.system

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))

Use asis :

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

Final notes

I've sum up all the previous code in two gists

Windows

macOS

Marc_Alx
  • 1,285
  • 17
  • 25
  • 1
    From Microsoft with love? – ChipJust Oct 02 '19 at 17:28
  • 1
    notifier = nManager.create_toast_notifier() # raises an exception Traceback (most recent call last): File "", line 1, in RuntimeError: Element not found. – ChipJust Oct 02 '19 at 17:47
  • Indeed it seems that recent update of windows (or API/Configuration changes) breaks this code. (other developper reported the same behavior in the comment section of my gist) – Marc_Alx Oct 07 '20 at 12:56
  • 1
    Is there any way to connect the buttons of the toast notification to an action? Or is there any way to get the inputs of the toast notification? – Andy_ye Jan 24 '21 at 14:29
  • winrt does not seem to be installable with pip in 3.11, winrt does not seem to be maintained anymore. There is a community supported fork though, winsdk – BoZenKhaa Mar 06 '23 at 12:34
6

You will need to use a 3rd party python GUI library or the pywin32 library. TkInter, the GUI toolkit that comes bundled with python does not support system tray pop ups.

Multiform neutral libraries that support working with the system tray:

  • wxPython
  • PyGTK
  • PyQT

Windows specific library that supports working with the system tray:

  • pywin32

Information/example of system tray pop ups using wxpython on windows:

Community
  • 1
  • 1
cnodell
  • 1,191
  • 2
  • 7
  • 8
  • Ok, any example of how to do it with wxPython? – Roman Rdgz Apr 10 '13 at 09:56
  • 1
    @RomanRdgz Have a look at [ToasterBox](http://xoomer.virgilio.it/infinity77/main/freeware.html#toasterbox) which I found in http://stackoverflow.com/questions/2240674/cross-platform-desktop-notifier-in-python. – halex Apr 10 '13 at 10:02
5

in Linux system , You could use inbuilt command notify-send.

ntfy library can be used for sending push notifications.

click here for ntfy documentation

installation:

sudo pip install ntfy

examples:

ntfy send "your message!"
ntfy -t "your custom title" send "your message"
chaha0s
  • 118
  • 7
jeevan
  • 113
  • 2
  • 4
  • 1
    I would add that this is a python program called from the command line and not an internal Python command – tc88 Oct 26 '17 at 05:49
-1

The easiest way of that is by using win10toast

This is the Code:

from win10toast import ToastNotifier

Notifi = ToastNotifier()  
Notifi.show_toast("Title", "Description")

This will may help you!