类和线程之间的函数指针

时间:2016-09-23 17:13:43

标签: python qt python-3.x

这是我的QT代码

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()

现在这是我的PS2231A库

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)

以下是我想要实现的目标: 电源提供过电流等紧急消息。它本质上最终将该消息写入串行端口而没有任何命令请求数据。收到该消息后,我希望GUI能够更改。

范围: 在这里,我正在为PS2231A编写库,用户将围绕它编写GUI。我想要一个库侧解决方案将消息传播到GUI,这是我设想的方式:

步骤1:创建PS2231A的对象时,启动一个线程,该线程将读取串行端口(轮询它)以获取消息。一旦读取紧急消息,它就会调用库中的函数。 步骤2:线程调用的函数应该执行用户想要的任何函数,即如果用户想要将GUI背景变为红色,则用户将代码写入名为turn_background_red的函数中,将函数名称传递给库函数。然后,只要调用紧急消息,库函数就会执行代码。

我认为下面的代码可以很好地解释这一点(我希望这会发生,所以有些代码不起作用):

QT代码

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()

类代码实现

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

我在思考这个问题时遇到的一些关键挑战是要执行的功能是在不同的类中。

1 个答案:

答案 0 :(得分:0)

你真的应该更多地修改你的问题(参见Minimal, Complete and Verifiable),但这里有一个解决方案,至少应该适用于Python 2.7和3.5:

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

这将检查类PS2231A的实例是否具有名为function_name的属性,如果它的类型是方法,则会调用它。

如果我犯了一些错误,请告诉我,请在手机上输入。