Unable to use wx.NotificationMessage properly with wxPython

后端 未结 2 664
有刺的猬
有刺的猬 2021-01-05 14:32

I recently upgraded to the development release of wxPython (wxPython 2.9.2.4) since I needed the functionality of wx.NotificationMessage within my application. I have been t

相关标签:
2条回答
  • 2021-01-05 14:50

    There is an undocumented hidden method in TaskBarIcon called ShowBalloon which is only implemented for Windows.

    From the source:

    def ShowBalloon(*args, **kwargs):
        """
        ShowBalloon(self, String title, String text, unsigned int msec=0, int flags=0) -> bool
    
        Show a balloon notification (the icon must have been already
        initialized using SetIcon).  Only implemented for Windows.
    
        title and text are limited to 63 and 255 characters respectively, msec
        is the timeout, in milliseconds, before the balloon disappears (will
        be clamped down to the allowed 10-30s range by Windows if it's outside
        it) and flags can include wxICON_ERROR/INFO/WARNING to show a
        corresponding icon
    
        Returns True if balloon was shown, False on error (incorrect parameters
        or function unsupported by OS)
    
        """
        return _windows_.TaskBarIcon_ShowBalloon(*args, **kwargs)
    

    I tested it on Windows with wxPython 2.9.4.0 and it works well.

    0 讨论(0)
  • 2021-01-05 14:58

    I would not recommend using 2.9 just yet. I have encountered some strange bugs when trying it out.

    You can have the same functionality in 2.8. I am using somewhat modified code that I have found some time ago.

    import wx, sys
    
    try:
        import win32gui #, win32con
        WIN32 = True
    except:
        WIN32 = False
    
    class BalloonTaskBarIcon(wx.TaskBarIcon):
        """
        Base Taskbar Icon Class
        """
        def __init__(self):
            wx.TaskBarIcon.__init__(self)
            self.icon = None
            self.tooltip = ""
    
        def ShowBalloon(self, title, text, msec = 0, flags = 0):
            """
            Show Balloon tooltip
             @param title - Title for balloon tooltip
             @param msg   - Balloon tooltip text
             @param msec  - Timeout for balloon tooltip, in milliseconds
             @param flags -  one of wx.ICON_INFORMATION, wx.ICON_WARNING, wx.ICON_ERROR
            """
            if WIN32 and self.IsIconInstalled():
                try:
                    self.__SetBalloonTip(self.icon.GetHandle(), title, text, msec, flags)
                except Exception:
                    pass # print(e) Silent error
    
        def __SetBalloonTip(self, hicon, title, msg, msec, flags):
    
            # translate flags
            infoFlags = 0
    
            if flags & wx.ICON_INFORMATION:
                infoFlags |= win32gui.NIIF_INFO
            elif flags & wx.ICON_WARNING:
                infoFlags |= win32gui.NIIF_WARNING
            elif flags & wx.ICON_ERROR:
                infoFlags |= win32gui.NIIF_ERROR
    
            # Show balloon
            lpdata = (self.__GetIconHandle(),   # hWnd
                      99,                       # ID
                      win32gui.NIF_MESSAGE|win32gui.NIF_INFO|win32gui.NIF_ICON, # flags: Combination of NIF_* flags
                      0,                        # CallbackMessage: Message id to be pass to hWnd when processing messages
                      hicon,                    # hIcon: Handle to the icon to be displayed
                      '',                       # Tip: Tooltip text
                      msg,                      # Info: Balloon tooltip text
                      msec,                     # Timeout: Timeout for balloon tooltip, in milliseconds
                      title,                    # InfoTitle: Title for balloon tooltip
                      infoFlags                 # InfoFlags: Combination of NIIF_* flags
                      )
            win32gui.Shell_NotifyIcon(win32gui.NIM_MODIFY, lpdata)
    
            self.SetIcon(self.icon, self.tooltip)   # Hack: because we have no access to the real CallbackMessage value
    
        def __GetIconHandle(self):
            """
            Find the icon window.
            This is ugly but for now there is no way to find this window directly from wx
            """
            if not hasattr(self, "_chwnd"):
                try:
                    for handle in wx.GetTopLevelWindows():
                        if handle.GetWindowStyle():
                            continue
                        handle = handle.GetHandle()
                        if len(win32gui.GetWindowText(handle)) == 0:
                            self._chwnd = handle
                            break
                    if not hasattr(self, "_chwnd"):
                        raise Exception
                except:
                    raise Exception, "Icon window not found"
            return self._chwnd
    
        def SetIcon(self, icon, tooltip = ""):
            self.icon = icon
            self.tooltip = tooltip
            wx.TaskBarIcon.SetIcon(self, icon, tooltip)
    
        def RemoveIcon(self):
            self.icon = None
            self.tooltip = ""
            wx.TaskBarIcon.RemoveIcon(self)
    
    # ===================================================================
    app = wx.PySimpleApp()
    
    class TestTaskBarIcon(BalloonTaskBarIcon):
    
        def __init__(self):
            wx.TaskBarIcon.__init__(self)
            # create a test icon
            bmp = wx.EmptyBitmap(16, 16)
            dc = wx.MemoryDC(bmp)
            dc.SetBrush(wx.RED_BRUSH)
            dc.Clear()
            dc.SelectObject(wx.NullBitmap)
    
            testicon = wx.EmptyIcon()
            testicon.CopyFromBitmap(bmp)
    
            self.SetIcon(testicon)
            self.Bind(wx.EVT_TASKBAR_LEFT_UP, lambda e: (self.RemoveIcon(),sys.exit()))
    
            self.ShowBalloon("", "Hello world!")
    
    icon = TestTaskBarIcon()
    app.MainLoop()
    
    0 讨论(0)
提交回复
热议问题