Невозможно правильно использовать wx.NotificationMessage с wxPython - PullRequest
6 голосов
/ 23 сентября 2011

Я недавно обновился до версии разработки wxPython (wxPython 2.9.2.4), поскольку мне требовалась функциональность wx.NotificationMessage в моем приложении.Я безуспешно пытался создать пузыри уведомлений о некоторых пользовательских событиях из-за чего-то, что я думаю, может быть возможной ошибкой.Перед тем, как отправлять такую ​​ошибку, я хотел бы продолжить и спросить людей из списка рассылки, что, по их мнению, может быть проблемой, и, надеюсь, найти решение в моем коде.

Вот код, который я использовал:

import wx, sys

app = wx.PySimpleApp()

class TestTaskBarIcon(wx.TaskBarIcon):

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

        wx.NotificationMessage("", "Hello world!").Show()

icon = TestTaskBarIcon()
app.MainLoop()

На моем компьютере с Windows 7 код создает маленький белый значок на панели задач и создает всплывающее окно с фразой «Hello World!».Эта проблема?Сообщение не на моей иконке.Создается еще один значок, и сообщение помещается туда.См. Это изображение: http://www.pasteall.org/pic/18068">

Я подумал, что это, вероятно, связано с тем, что я не передал родительский параметр в строке 22:

wx.NotificationMessage("", "Hello world!").Show()

Вот что я изменил:

wx.NotificationMessage("", "Hello world!", self).Show()

Где «я» относится к значку панели задач.Когда я это делаю, я получаю сообщение об ошибке:

Traceback (most recent call last):
  File "C:\Python27\testnotificationmessage.py", line 24, in <module>
    icon = TestTaskBarIcon()
  File "C:\Python27\testnotificationmessage.py", line 22, in __init__
    wx.NotificationMessage("", "Hello world!", self).Show()
  File "C:\Python27\lib\site-packages\wx-2.9.2-msw\wx\_misc.py", line 1213, in __init__
    _misc_.NotificationMessage_swiginit(self,_misc_.new_NotificationMessage(*args))
TypeError: in method 'new_NotificationMessage', expected argument 3 of type 'wxWindow *'

Что происходит?Если я удалю этот аргумент, я не получу свой результат, если я добавлю аргумент, я получу ошибку!Как я должен использовать wx.NotificationMessage с wx.TaskBarIcon!

Пожалуйста, помогите!Я надеюсь, что предоставил достаточно деталей.Пожалуйста, прокомментируйте, если вам нужно больше!

Ответы [ 2 ]

10 голосов
/ 23 сентября 2011

Я бы не рекомендовал использовать 2.9 только сейчас.Я столкнулся с некоторыми странными ошибками при попытке.

Вы можете иметь ту же функциональность в 2.8.Я использую несколько измененный код, который я нашел некоторое время назад.

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()
6 голосов
/ 27 августа 2012

Существует недокументированный скрытый метод в TaskBarIcon, называемый ShowBalloon, который реализован только для Windows.

Из источника :

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протестировал его на Windows с wxPython 2.9.4.0, и он хорошо работает.

...