Search code examples
pythonwxpython

How to get a variable from a different class?


I have a class named TerminalPanel which has the following method:

def OnSerialRead(self, event):
    """Handle input from the serial port."""
    text = event.data

Now, I want to get the value of text from another method (get_data) in another class (GraphicsPanel).

How do I get this value? I tried marito = TerminalPanel.OnserialRead.text, but I get AttributeError: 'function' object has no attribute 'text'


Update

I have set-up the TerminalPanel class to include the variable text as part of it:

def OnSerialRead(self, event):
    """Handle input from the serial port."""
    self.text = event.data

But now when I call it like this: marito = TerminalPanel.text inside my GraphicsPanel class I get the following error:

AttributeError: type object 'TerminalPanel' has no attribute 'text'

What am I doing wrong?


Solution

  • I think the problem is a lack of context and confusion what actually to do. I suppose you try to rework the wxTerminal.py from pyserial. I have to admit this part of pyserial is neither very readable (has been created by wxGlade) nor is it easy to understand (requires understanding of the wxPython event system and spinning off of threads (to keep the GUI responsive when reading on the serial port).

    However, according to your problem description, it seems to me you want to do the following:

    Get the value of event.text when it arrives and process it further in your GraphicsPanel instance.

    You have to possibilities:

    1) Bind to the event:

    In your GraphicsPanel class:

    class GraphicsPanel(wx.Panel):
        def __init__(...):
            ...
            self.parent = self.GetParent() # this should result in a wx.Frame instance!
            # binding on wx.Frame required, because wx.Panel will not catch the event
            self.parent.Bind(EVT_SERIALRX, self.OnSerialRead)
    
        def OnSerialRead(self, event):
            text = event.text
            ...
            event.Skip() # important: you have to skip it also in ``TerminalPanel`` if you
            # want to bind twice 
    

    2) Call the routine in GraphicsPanel instance with event.text as argument.

    class TerminalPanel(wx.Panel):
        def __init__(...):
            ...
            self._grphpnl = GraphicsPanel(...)
            self.Bind(EVT_SERIALRX, self.OnSerialRead)
    
        def OnSerialRead(self, event):
            text = event.text
            # do something with it in GraphicsPanel instance
            self._grphpnl.OnSerialText(text)
            ...
    

    Somewhere else in your code:

    class GraphicsPanel(wx.Panel):
        ...
        def OnSerialText(text):
            # do something with the text