Phoenix icon indicating copy to clipboard operation
Phoenix copied to clipboard

wx notification events, Assertion Error

Open diamondStar35 opened this issue 4 months ago • 1 comments

Operating system: Windows 10 22H2: 64 bit wxPython version & source: Wx python 4.2.3, on python 64 bit. Installed via pip. Python version & source: Python 3.1.1.10: 64 bit, Official python installer.

Description of the problem: The below code triggers a wx notification event, with 2 actions. I get an Assertion Error when trying to bind the events, See below: Traceback (most recent call last): File "D:\python\wx_notification.py", line 33, in OnShowNotification self.Bind(wx.adv.wxEVT_NOTIFICATION_MESSAGE_ACTION, self.OnNotificationAction) File "C:\Users\Nolan\AppData\Local\Programs\Python\Python311\Lib\site-packages\wx\core.py", line 1470, in _EvtHandler_Bind assert isinstance(event, wx.PyEventBinder) AssertionError

Code Example (click to expand)
import wx
import wx.adv

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='wxPython Notification Example')
        self.panel = wx.Panel(self)
        
        # Button to trigger the notification (for demo)
        btn = wx.Button(self.panel, label='Show Notification')
        btn.Bind(wx.EVT_BUTTON, self.OnShowNotification)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(btn, 0, wx.ALL, 10)
        self.panel.SetSizer(sizer)
        
        self.Show()
    
    def OnShowNotification(self, event):
        # Create the notification
        notification = wx.adv.NotificationMessage(
            title="Notification Title",
            message="This is the notification message body.",
            parent=self,
            flags=wx.ICON_INFORMATION
        )
        
        # Add actions (buttons)
        notification.AddAction(1001, "Action 1")  # Custom ID and label
        notification.AddAction(1002, "Action 2")
        
        # Bind the action event handler
        self.Bind(wx.adv.wxEVT_NOTIFICATION_MESSAGE_ACTION, self.OnNotificationAction)
        
        # Show the notification (auto-timeout)
        if not notification.Show(timeout=wx.adv.NotificationMessage.Timeout_Auto):
            print("Error showing notification")  # Handle if unsupported
    
    def OnNotificationAction(self, event):
        action_id = event.GetId()
        if action_id == 1001:
            print("Action 1 clicked!")
        elif action_id == 1002:
            print("Action 2 clicked!")
        event.Skip()  # Allow default handling if needed

if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame()
    app.MainLoop()

diamondStar35 avatar Aug 24 '25 16:08 diamondStar35

The assertion is correct as wxEVT... is just an event id. You would need to bind to wx.adv.EVT_NOTIFICATION_MESSAGE_ACTION instead, but that has been missing from etg/notifymsg.py and therefore is not available in wx.adv. As workaround you could use code like this:

wx.adv.EVT_NOTIFICATION_MESSAGE_ACTION = wx.PyEventBinder(wx.adv.wxEVT_NOTIFICATION_MESSAGE_ACTION, 1)

and then bind to wx.adv.EVT_NOTIFICATION_MESSAGE_ACTION.

Are you in the position to build wxPython yourself, test and submit a PR? Code like this needs to be added to etg/notifymsg.py:

    module.addPyCode("""\
        EVT_NOTIFICATION_MESSAGE_CLICK= wx.PyEventBinder( wxEVT_NOTIFICATION_MESSAGE_CLICK, 1 )
        EVT_NOTIFICATION_MESSAGE_DISMISSED = wx.PyEventBinder( wxEVT_NOTIFICATION_MESSAGE_DISMISSED, 1 )
        EVT_NOTIFICATION_MESSAGE_ACTION = wx.PyEventBinder( wxEVT_NOTIFICATION_MESSAGE_ACTION, 1 )
        """)

DietmarSchwertberger avatar Aug 24 '25 19:08 DietmarSchwertberger