Function pointer across classes and threads
<p>Here is my QT code</p>

<pre><code>from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QTime
from PyQt4.QtGui import QApplication
from keithley.PS2231A import PS2231A

class A(QtGui.QMainWindow, gui.Ui_MainWindow):
    def __init__(self, parent=None):
        super(A, self).__init__(parent)
        self.setupUi(self)
        ps = PS2231A(port='COM8')
        self.refresh.clicked.connect(self.get_data)

     def get_data(self):
        data = ps.read_current()
        self.current_measurement.setText(str(data))

def main():
    app = QtGui.QApplication([])
    form = A()
    form.show()
    app.exec()

if __name__ == '__main__':
    main()
</code></pre>

<p>Now here is my PS2231A library</p>

<pre><code>class PS2231A:
    def __init__(self, port: str):
        self._port = port
        self._dev = serial.Serial()
        self._dev.port = self._port
        self._dev.timeout = 5
        self._dev.baudrate = 9600
        self.connect()
        self._dev.open()

    def read_current(self):
        self._dev.write('MEAS:CURR?')
        current = self._dev.readline()
        return float(current)
</code></pre>

<p>Here is what I would like to achieve:
The power supply provides emergency messages like over current. It essentially ends up writing that message to serial port without any command requesting data. As soon as that message is received, I would want the GUI to change.</p>

<p>Scope:
Here I am writing the library for PS2231A, and a user will be writing a GUI around it. I would like a library side solution to propagate the message to GUI, here is how I envision it:</p>

<p>Step 1: When an object of PS2231A is created, start a thread, which will read the serial port (poll it) for messages. Once the emergency message is read, it calls a function in the library.
Step 2: The function being called by the thread, should execute any function that the user wants, i.e. if the user wants to turn the GUI background to red, the user writes the code in a function named turn_background_red, passes the function name to the library function. Then the library function executes the code whenever the emergency message is called. </p>

<p>I think the code below will explain this well (I want this to happen, so some code will not work):</p>

<p>QT Code</p>

<pre><code>from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QTime
from PyQt4.QtGui import QApplication
from keithley.PS2231A import PS2231A

class A(QtGui.QMainWindow, gui.Ui_MainWindow):
    def __init__(self, parent=None):
        super(A, self).__init__(parent)
        self.setupUi(self)
        ps = PS2231A(port='COM8')
        ps.set_over_current_callback(self.warn_user)
        self.refresh.clicked.connect(self.get_data)

     def warn_user(self):
        # manipulate some GUI element
        # implemented by user

     def get_data(self):
        data = ps.read_current()
        self.current_measurement.setText(str(data))

def main():
    app = QtGui.QApplication([])
    form = A()
    form.show()
    app.exec()

if __name__ == '__main__':
    main()
</code></pre>

<p>Class code implementation</p>

<pre><code>class PS2231A:
    def __init__(self, port: str):
        self._port = port
        self._dev = serial.Serial()
        self._dev.port = self._port
        self._dev.timeout = 5
        self._dev.baudrate = 9600
        self.connect()
        self._dev.open()

    def read_current(self):
        self._dev.write('MEAS:CURR?')
        current = self._dev.readline()
        return float(current)

    def set_over_current_callback(self, function_name):
        # write some code to run the function name passed to this function
        # This is the code I am not sure how to go ahead with

        # This function will be executed if an emergency message is received
        # on serial port
</code></pre>

<p>Some critical challenges I faced when thinking about this were that the function to be executed is in different class. </p>

<p>You really should revise your question more (see <a href="http://stackoverflow.com/help/mcve">Minimal, Complete and Verifiable</a>), but here is one solution, that should work for at least for both Python 2.7 and 3.5:</p>

<pre><code>import types

class PS2231A:

    # Rest of your class

    def set_over_current_callback(self, function_name):
        func = getattr(self, function_name, None)
        if isinstance(func, types.MethodType):
            func()
        return
</code></pre>

<p>This checks if the instance of class <code>PS2231A</code> has an attribute with the name <code>function_name</code> and if it's type is method, it gets called. </p>

<p>Let me know if I made some mistake, typed this on a phone.</p>

python qt python-3.x