Sending/Using Data with wx.lib.pubsub

I've read the doc pages for wx.lib.pubsub and the Publisher class, but am
still unclear on how to use the data attribute correctly.

   For example, in one module the method for a change in variable begins with
the statement:

   newvar = self.vname.GetValue()

and ends with the broadcast:

   Publisher().sendMessage(self.appData.projVars, data=None)

   If I replace data=None with data=newvar, is the string for newvar
transmitted with the message?

   If that's the case, how do I access the value of that data in the module
receiving the message? In the method called when the broadcast is received,
can I assign that data name to a new variable for use in the subscribed
function, for example:

   shown = newvar
?

Rich

···

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

  I've read the doc pages for wx.lib.pubsub and the Publisher class, but am
still unclear on how to use the data attribute correctly.

  For example, in one module the method for a change in variable begins with
the statement:

       newvar = self.vname.GetValue()

and ends with the broadcast:

       Publisher().sendMessage(self.appData.projVars, data=None)

  If I replace data=None with data=newvar, is the string for newvar
transmitted with the message?

Hi Rich,
Yes, it is sent.
...

  If that's the case, how do I access the value of that data in the module
receiving the message? In the method called when the broadcast is received,
can I assign that data name to a new variable for use in the subscribed
function, for example:

       shown = newvar
?

The subscribed function should look something like this:

def SubscribedFunction(self, message):
    newvar = message.data
    etc.

I had to do some experimenting initially to figure this out. Note
that the data can be any python object. If I recall correctly,
message.topic will be the topic from the sendMessage call
(yourclassobject.appData.projVars from your example above.)

-Chris Botos

···

On 9/29/07, Rich Shepard <rshepard@appl-ecosys.com> wrote:

Yes, it is sent.

Chris,

   I assumed this to be the case, but the more important question is the one
about how it's used by the receiver ...

The subscribed function should look something like this:

def SubscribedFunction(self, message):
   newvar = message.data
   etc.

   ... which you've answered for me.

I had to do some experimenting initially to figure this out. Note that
the data can be any python object. If I recall correctly, message.topic
will be the topic from the sendMessage call
(yourclassobject.appData.projVars from your example above.)

   I'm not sufficiently experienced with python to have figured this out
myself. The brief docs don't address it at all.

Thank you very much,

Rich

···

On Mon, 1 Oct 2007, chris botos wrote:

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Chris,

   I'm missing something crucial in the syntax because I cannot get it
working here.

   I use a module, config.py, as a blackboard to share variables among
modules. This is where the messages to be published are found. For
example, there's the publisher message 'projVars' in this module. config.py
is imported into all other modules and assigned to the variable
'self.appData'.

   The sending module has the line:

   Publisher().sendMessage(self.appData.projVars, data=newvar)

   The listening module has this line:

   Publisher().subscribe(self.loadParVar, self.appData.projVars)

In this listener module I just added the function:

     def projVars(self, message):
       self.newvar = self.appData.projVars.data

but the variable 'self.newvar' is not seen when I try to use it in another
function:

   File "/data1/eikos/fuzSetPage.py", line 391, in loadParVar
     self.dispVar = self.newvar
AttributeError: 'modFzySet' object has no attribute 'newvar'

   So I've missed something in your reply on implementing the function for
the subscribed function. Is what I've missed visible in what I include
above?

TIA,

Rich

···

On Mon, 1 Oct 2007, chris botos wrote:

The subscribed function should look something like this:

def SubscribedFunction(self, message):
   newvar = message.data
   etc.

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Rich,

Rich Shepard wrote:

The subscribed function should look something like this:

def SubscribedFunction(self, message):
   newvar = message.data
   etc.

Chris,

  I'm missing something crucial in the syntax because I cannot get it
working here.

  I use a module, config.py, as a blackboard to share variables among
modules. This is where the messages to be published are found. For
example, there's the publisher message 'projVars' in this module. config.py
is imported into all other modules and assigned to the variable
'self.appData'.

  The sending module has the line:

    Publisher().sendMessage(self.appData.projVars, data=newvar)

  The listening module has this line:

    Publisher().subscribe(self.loadParVar, self.appData.projVars)

In this listener module I just added the function:

      def projVars(self, message):
        self.newvar = self.appData.projVars.data

Shouldn't this be:
            self.newvar = message.data

but the variable 'self.newvar' is not seen when I try to use it in another
function:

  File "/data1/eikos/fuzSetPage.py", line 391, in loadParVar
    self.dispVar = self.newvar
AttributeError: 'modFzySet' object has no attribute 'newvar'

If no message was ever received, i.e. before you call the above line 391 then this would be normal.

Maybe you want to initialize self.newvar to e.g. None during the init of fuzSetPage.py.

Werner

···

On Mon, 1 Oct 2007, chris botos wrote:

  So I've missed something in your reply on implementing the function for
the subscribed function. Is what I've missed visible in what I include
above?

TIA,

Rich

Shouldn't this be:
          self.newvar = message.data

Werner,

   I thought that I had tried that first, but perhaps not. I'll try it again.

Maybe you want to initialize self.newvar to e.g. None during the init of fuzSetPage.py.

   I'll try that, too.

Thanks,

Rich

···

On Mon, 1 Oct 2007, Werner F. Bruhin wrote:

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Well, I get no python errors, but the subscribed page is not loading the
appropriate data in the widgets. I'll explore why.

Thanks to you and Chris,

Rich

···

On Mon, 1 Oct 2007, Rich Shepard wrote:

Shouldn't this be:
          self.newvar = message.data

Maybe you want to initialize self.newvar to e.g. None during the init of fuzSetPage.py.

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Rich,

With Werner's comments, and the intervening time, you may have solved
this already. I'm a little confused about your program structure, but
I have a couple of comments.

> The subscribed function should look something like this:
>
> def SubscribedFunction(self, message):
> newvar = message.data
> etc.

Chris,

  I'm missing something crucial in the syntax because I cannot get it
working here.

  I use a module, config.py, as a blackboard to share variables among
modules. This is where the messages to be published are found. For
example, there's the publisher message 'projVars' in this module. config.py
is imported into all other modules and assigned to the variable
'self.appData'.

  The sending module has the line:

       Publisher().sendMessage(self.appData.projVars, data=newvar)

  The listening module has this line:

       Publisher().subscribe(self.loadParVar, self.appData.projVars)

The signature for the subscribe method is:
    Publisher().subscribe(listenerMethod, topic)

So your subscribe call is saying that there is a method
"self.loadParVar" that will be called when the topic
"self.appData.projVars" is published, as in your
Publisher().sendMessage(...) call. If you keep rthe subscribe as is, then
you need a method defined like the following:

def loadParVar(self, message):
    received_newvar = message.data
    # received_newvar, should now be the value 'newvar'
    # from your sendMessage call.
    ...

In this listener module I just added the function:

         def projVars(self, message):
           self.newvar = self.appData.projVars.data

but the variable 'self.newvar' is not seen when I try to use it in another
function:

As Werner mentioned, you need "self,newvar = message.data". The
Publisher calls your listener function with the sendMessage data value
embedded in the message object that is the listener function's first
argument.

Also, the method projVars was not specified as the listener, so I
don't think it is *ever* called. As was pointed out, when some other
function tries to use self.newvar, it crashes because it was never
created.

  File "/data1/eikos/fuzSetPage.py", line 391, in loadParVar
    self.dispVar = self.newvar
AttributeError: 'modFzySet' object has no attribute 'newvar'

I'm thinking you must already have a method called loadParVar that
takes at least one argument. It must have been called by the
Publisher, or I think python would have died when the Publisher called
it before self.newvar was ever referenced.

From Werner's suggestion, initializing self.newvar to None would solve

the attribute error. But I'm thinking whatever is using it must be
tolerant of the None value, or again something would have crashed
because of an illegal None type value. I think the fact that python
doesn't crash just means that the original problem with getting your
listener called correctly is being masked. If your widgets being
updated correctly is dependent on the value of "newvar", then then
they wouldn't be.

  So I've missed something in your reply on implementing the function for
the subscribed function. Is what I've missed visible in what I include
above?

I think so, iff I am correctly interpreting what you are doing and how
your modules are scoped. So (1) Make sure you are calling the exact
method you specify in the subscribe, and (2) get your data from its
first argument as shown.

I hope this helps. Or even better, I hope you've already solved it!

- Chris

···

On 10/1/07, Rich Shepard <rshepard@appl-ecosys.com> wrote:

On Mon, 1 Oct 2007, chris botos wrote:

With Werner's comments, and the intervening time, you may have solved this
already. I'm a little confused about your program structure, but I have a
couple of comments.

Chris,

   No, it's not solved. But ... I think you've clarified where the message
goes in the listener.

The signature for the subscribe method is:
   Publisher().subscribe(listenerMethod, topic)

So your subscribe call is saying that there is a method "self.loadParVar"
that will be called when the topic "self.appData.projVars" is published,
as in your Publisher().sendMessage(...) call. If you keep rthe subscribe
as is, then you need a method defined like the following:

   That's correct.

def loadParVar(self, message):
   received_newvar = message.data
   # received_newvar, should now be the value 'newvar'
   # from your sendMessage call.

   I think this is what I need to add rather than a separate function (which
is how I interpreted Werner's comments).

   I'll try it tomorrow morning.

As Werner mentioned, you need "self,newvar = message.data". The Publisher
calls your listener function with the sendMessage data value embedded in
the message object that is the listener function's first argument.

   Ah! That makes it much more clear.

Also, the method projVars was not specified as the listener, so I don't
think it is *ever* called.

   No. projVars is the message broadcast. loadParVar is the listener's
function.

   Will report back tomorrow.

Thanks,

Rich

···

On Mon, 1 Oct 2007, chris botos wrote:

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Chris,

   Changing the function to the above throws no errors, but that tab's widgets
aren't displaying the values they should.

   I'll work on this as time permits. By having the sending module copy the
reference variables to the "blackboard" module so the subscribing module can
copy them from there works.

Again, thank you very much for your patient help,

Rich

···

On Mon, 1 Oct 2007, chris botos wrote:

def loadParVar(self, message):
   received_newvar = message.data
   # received_newvar, should now be the value 'newvar'
   # from your sendMessage call.
   ...

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863