[wxPython-users] Re: "Pushing" Data to Modules

Werner F. Bruhin werner.bruhin at free.fr
Sun Dec 3 14:43:37 PST 2006


Hi Rich,

Rich Shepard wrote:
> On Sat, 2 Dec 2006, Werner F. Bruhin wrote:
>
>> Not that I am expert on this but here is a revised version of what I 
>> used to get a hang of pubsub.
>
> Werner,
>
>   Looking at what you sent, and the wx.lib.pubsub API doc page is 
> getting me
> closer, and with less code than you used. The error I'm getting now is:
>
>   File
> "/usr/lib/python2.4/site-packages/wx-2.6-gtk2-unicode/wx/lib/pubsub.py",
> line 670, in validate
>     raise TypeError, 'Listener '+`listener+' lacking arguments!'
> TypeError: Listener <bound method modPolicy.setWidgets of
> <policyPage.modPolicy; proxy of C++ wxPanel instance at
> _18544408_p_wxPanel>> lacking arguments!
What is the "def" for policyPage.modPolicy?  See below for the 
NeedChoiceRefresh stuff.
>
> so it appears that by 'importing wx.lib.pubsub as Publisher' I've exposed
> what's neede. Now it's a matter of structuring the arguments properly.
Yes, I think the module mypublisher.py is only needed if one wants to 
use variables instead of strings.
> Unfortunately, the API doc page uses ellipses in the parentheses 
> rather than
> clue sticks for beginning users like me.
Any Python object is accepted, i.e. ('something', 'whatever') a tuple or 
[] a list or {} a dict or whatever other object.

>
>   In config.py (the application-visible variables) I have added:
>     projOpen = 1 # publisher message that a project file's opened
>
>   Next, in DBmethods.DBtools().openDB() I have:
>     self.pubData = self.appData.projName
>     self.Publisher().sendMessage(projOpen, self.pubData)
> which are probably mal-formed. I'm not sure what to put in the 
> arguments to
> self.Publisher().sendMessage().
>
>   Finally, in modPolicy().__init__() I have the line generating the 
> error:
>
>     self.polSub = Publisher().subscribe(self.setWidgets, 
> self.appData.projOpen)
>
>   I tried to follow the model in your example of having the
> Publisher().subscribe parameters of the function to call and the message
> that triggers calling that function. Obviously, I missed.
Does your code look something like:
    def setWidgets(self, msg):
       msg.topic
       msg.data
>
>
>   The trick to using wx.lib.pubsub seems to be understanding what to 
> put in
> the parentheses of the subscribe and sendMessage methods.
The way I understand it (wxPython 2.6.3, don't know if it changed in 2.7).

    # to subscribe
    mypub.publisher.subscribe(functionToCall, mypub.statusText)

Above could also be:
    # to subscribe
    mypub.publisher.subscribe(functionToCall, 'statusText')

The "functionToCall" is what ever method/function you want to call and 
it accepts the "data", e.g.:

If you look a mypublisher.py it has:
def MyPrint(msg):
    print '****************'
    print 'for testing only'
    print msg.topic
    print msg.data
    print '****************'

Above "MyPrint" is the functionToCall and "msg" contains the data and it 
has an attribute "topic" (e.g. 'statusText' and an attribute "data" 
(e.g. the string to be shown in the statustext) which can be any valid 
Python object (you define what it is and it can be different for each 
topic).

See you also MySetStatusText in pubsubtest.py:
    def MySetStatusText(self, msg):
        self.statusBar1.SetStatusText(msg.data, 0)

Now the notify stuff would be:
    # to notify
    mypub.publisher.sendMessage(mypub.statusText, 'Text for status line')

Or:
    # to notify
    mypub.publisher.sendMessage('statusText', 'Text for status line')

Something more complex could be the stuff I use in my application for 
comboboxes, e.g. in the dialog which maintains the entries for a 
combobox I do something along the following.

E.g. in the dialog which  maintains wine regions I do this when closing 
the dialog.

        mypub.publisher.sendMessage(mypub.comboBoxRefresh, 'region_ls')

In my generic combobox module I subscribe to both the refresh for a 
particular table (first one below) and a generic refresh (second one 
below) of all comboboxes.

            mypub.publisher.subscribe(self.NeedChoiceRefresh, 
(mypub.comboBoxRefresh, self.dbTable))
            mypub.publisher.subscribe(self.NeedChoiceRefresh, 
mypub.comboBoxRefresh)

Note that the first line above is the more specific one, i.e. if this is 
the instance for a "region_ls" type combobox the function 
"NeedChoiceRefresh" is called, or it is called if the publisher does not 
specify a table name, i.e.

        mypub.publisher.sendMessage(mypub.comboBoxRefresh)

Here is what NeedChoiceRefresh looks like:

def NeedChoiceRefresh(self, msg):
        self.initDone = False
        try:
            self.LoadChoices()
        except wx.PyDeadObjectError:
            pass

"initDone" is needed by LoadChoices - don't worry about it, the except 
was needed in case the combobox is being destroyed.

Hope this helps and does not cause more confusion.

Werner





More information about the wxpython-users mailing list