NOTE: This article is for wxPython 2.9-3.0. If you are using wxPython 4, you should go to my newer article
Several years ago, I wrote a tutorial about wxPython 2.8 and its built-in pubsub module which you can read here. Back then, a new API for pubsub was added in wxPython 2.8.11.0 that could be enabled by doing the following:
import wx.lib.pubsub.setupkwargs from wx.lib.pubsub import pub
The old way of importing pubsub was to do the following:
from wx.lib.pubsub import Publisher
Now in wxPython 2.9, it has changed to this:
from wx.lib.pubsub import pub
Thus you cannot use the code in my old tutorial any more and expect it to work in the latest version of wxPython. So it's time to update the tutorial a bit.
Let's take the original code from the old article and spruce it up using pubsub's newer API. It won't take very long. In fact, it's a very minor code change. Let's take a look!
import wx from wx.lib.pubsub import pub ######################################################################## class OtherFrame(wx.Frame): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame") panel = wx.Panel(self) msg = "Enter a Message to send to the main frame" instructions = wx.StaticText(panel, label=msg) self.msgTxt = wx.TextCtrl(panel, value="") closeBtn = wx.Button(panel, label="Send and Close") closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose) sizer = wx.BoxSizer(wx.VERTICAL) flags = wx.ALL|wx.CENTER sizer.Add(instructions, 0, flags, 5) sizer.Add(self.msgTxt, 0, flags, 5) sizer.Add(closeBtn, 0, flags, 5) panel.SetSizer(sizer) #---------------------------------------------------------------------- def onSendAndClose(self, event): """ Send a message and close frame """ msg = self.msgTxt.GetValue() pub.sendMessage("panelListener", message=msg) pub.sendMessage("panelListener", message="test2", arg2="2nd argument!") self.Close() ######################################################################## class MyPanel(wx.Panel): """""" #---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent) pub.subscribe(self.myListener, "panelListener") btn = wx.Button(self, label="Open Frame") btn.Bind(wx.EVT_BUTTON, self.onOpenFrame) #---------------------------------------------------------------------- def myListener(self, message, arg2=None): """ Listener function """ print "Received the following message: " + message if arg2: print "Received another arguments: " + str(arg2) #---------------------------------------------------------------------- def onOpenFrame(self, event): """ Opens secondary frame """ frame = OtherFrame() frame.Show() ######################################################################## class MyFrame(wx.Frame): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="New PubSub API Tutorial") panel = MyPanel(self) self.Show() #---------------------------------------------------------------------- if __name__ == "__main__": app = wx.App(False) frame = MyFrame() app.MainLoop()
As we have already discussed, the import is different. Let's see what else has changed. In the panel class, we create a listener like this:
pub.subscribe(self.myListener, "panelListener")
The myListener method can accept one or more arguments. In this case, we set it up to always require one argument (message) and an optional argument (arg2). Next we turn to the OtherFrame class where we need to take a look at the onSendAndClose method. In this method, we find that it sends out two messages:
msg = self.msgTxt.GetValue() pub.sendMessage("panelListener", message=msg) pub.sendMessage("panelListener", message="test2", arg2="2nd argument!") self.Close()
The first one just sends the required information whereas the second one sends both. You will note that the new API requires the use of explicit keyword arguments. If you change the first sendMessage command to pub.sendMessage("panelListener", msg), you will receive a TypeError exception.
That was a pretty simple change, eh? I think the new pubsub API is actually more readable and a little less "magical" than the original. Hopefully you will too. Have fun and happy coding!
Copyright © 2024 Mouse Vs Python | Powered by Pythonlibrary