2016-09-23 2 views
0

Hier ist mein QT CodeFunktionszeiger über Klassen und Threads

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

Hier ist meine PS2231A Bibliothek

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) 

Hier ist, was ich erreichen möchte: Die Stromversorgung liefert Notfallmeldungen wie über Strom. Es endet im Wesentlichen damit, diese Nachricht an den seriellen Port zu schreiben, ohne dass ein Befehl Daten anfordert. Sobald diese Nachricht empfangen wird, möchte ich, dass sich die GUI ändert.

Scope: Hier schreibe ich die Bibliothek für PS2231A, und ein Benutzer wird eine GUI um es schreiben. Ich möchte eine librarieseitige Lösung, um die Nachricht an die GUI zu propagieren, hier ist, wie ich es mir vorstelle:

Schritt 1: Wenn ein Objekt von PS2231A erstellt wird, starten Sie einen Thread, der die serielle Schnittstelle lesen wird für Nachrichten. Sobald die Notfallnachricht gelesen wurde, ruft sie eine Funktion in der Bibliothek auf. Schritt 2: Die vom Thread aufgerufene Funktion sollte alle vom Benutzer gewünschten Funktionen ausführen, dh wenn der Benutzer den GUI-Hintergrund in Rot umwandeln möchte, schreibt der Benutzer den Code in eine Funktion namens turn_background_red, übergibt den Funktionsnamen an die Bibliotheksfunktion. Dann führt die Bibliotheksfunktion den Code immer dann aus, wenn die Notfallnachricht aufgerufen wird.

Ich denke, der Code darunter auch erklären (ich dies geschehen soll, so dass einige Code funktioniert nicht):

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

Klasse Code-Implementierung

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 

Einige kritische Herausforderungen, denen ich dabei gegenüberstand, waren, dass die auszuführende Funktion in einer anderen Klasse ist.

+1

Wenn Sie feststellen, dass Ihre Frage in einem ersten Entwurf nicht klar ist, müssen Sie die Frage nicht wirklich * posten *. Mach einfach weiter, bis du denkst, dass es klar und bereit zum Lesen ist. –

+0

Code anzeigen. Das ist so vage, dass Sie uns grundsätzlich bitten, das Projekt für Sie zu schreiben. –

+1

An dieser Stelle haben Sie jedoch keine * konkrete, umsetzbare Frage * in Ihrem Beitrag. Stack Overflow eignet sich nicht wirklich für vage Architektur-Brainstorming-Fragen, tut mir leid. –

Antwort

0

Sie sollten wirklich Ihre Frage mehr revidieren (siehe Minimal, Complete and Verifiable), aber hier ist eine Lösung, die für zumindest für beide Python 2.7 und 3.5 funktionieren sollte: PS2231A

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 

Diese prüft, ob die Instanz der Klasse hat ein Attribut mit dem Namen function_name und wenn es Typ ist Methode, wird es aufgerufen.

Lassen Sie mich wissen, wenn ich einen Fehler gemacht habe, tippte das auf einem Telefon.

+0

Ich denke, das wird funktionieren, wenn der Funktionsname aus der Klasse PS2231A stammt, aber ich weiß nicht, ob diese Lösung funktioniert, wenn der Funktionsname, der an set_over_current_callback übergeben wurde, aus einer anderen Klasse stammt. Was denken Sie? –

+0

Auch, da ich Stack overflow sehr neu bin, können Sie mir helfen, diese Frage zu überarbeiten, so dass dies auch für andere eine hilfreiche Ressource werden kann. Ich werde den Link in dir lesen und werde die Frage aktualisieren, möchte dir Feedback geben. –

+0

Ok, gut, es würde helfen, wenn Sie klarstellen könnten, wo genau die Funktionen sind, die aufgerufen werden müssen? _i.e. Wenn der Benutzer den GUI-Hintergrund in Rot umwandeln möchte, schreibt der Benutzer den Code in eine Funktion mit dem Namen turn_background_red_. Bedeutet dies, dass der Benutzer _die Funktion _schreibt? Wo schreiben sie es? Wenn es viele Funktionen gibt, die mit unterschiedlichen Parametern über einen Socket aufgerufen werden müssen, wäre es besser, ein echtes Protokoll mit Nachrichten zu schreiben, die kodiert und dekodiert werden können. Oder wenn Sie meinen, dass der Benutzer die Funktion auf die Seite _client_ schreibt, dann ist das ein anderes Thema. –