2016-05-12 17 views
1

Community!Python DBus Signal entfernen (Signalempfänger entfernen)

Ich habe ein kleines Problem mit der Python-DBus-API. Ich erstelle einen Signalempfänger und er macht seine Arbeit. Wenn ich jedoch versuche, das Signal zu entfernen, wird es nicht entfernt und der Signalhandler (sigHandler) wird jedes Mal glücklich gerufen, wenn das Signal übereinstimmt.

class A(threading.Thread) 
    bus = None 
    mainloop = None 
    systemBusMainLoop = None 
    signalReceiver = None 

    def __init__(self,dbusMainLoop): 
     log("Hello.") 
     super(A, self).__init__() 
     gobject.threads_init() 
     self.mainloop = gobject.MainLoop() 
     self.systemBusMainLoop = dbusMainLoop 
     self.bus = dbus.SystemBus(mainloop=dbusMainLoop) 
     self.signalReceiver = self.bus.add_signal_receiver(self.sigHandler, 
      bus_name="org.bluez", 
      dbus_interface="org.freedesktop.DBus.Properties", 
      signal_name="PropertiesChanged", 
      path_keyword="path") 


    def run(self): 
     self.mainloop.run() 
     log("Running.") 

    def end(self): 
     log("Shutting down...") 
     self.bus.remove_signal_receiver(self.sigHandler, 
      self.signalReceiver, 
      dbus_interface="org.freedesktop.DBus.Properties") 
     #self.signalReceiver.remove() #tried this also 
     if (self.mainloop): 
      self.mainloop.quit() 
     del self.signalReceiver 
     log("Bye.") 

    def sigHandler(self, interface, changed, invalidated, path) 
     print interface 
     print changed 
     print invalidated 
     print path 

Genannt:

dbusA = A(dbusMainLoop=dbus.mainloop.glib.DBusGMainLoop()) 
dbusA.run() 
#doing something unrelated 
dbusA.end() #remove the Signal 
del dbusA 

Muss ich etwas verpasst? Warum wird mein sigHandler nicht entfernt (oder warum wird meine Übereinstimmung nicht entfernt).

Vielen Dank im Voraus!

Antwort

0

Die Zeile, die Sie auskommentiert haben (self.signalReceiver.remove()) funktioniert.

add_signal_receiver() gibt eine SignalMatch Instanz zurück, auf der Sie die Methode remove() aufrufen können, um den Rückruf rückgängig zu machen.

Das Problem in Ihrem Code-Snippet ist, dass dbusA.run() ist ein blockierender Anruf, weil es self.mainloop.run() ruft, die selbst ein blockierender Anruf ist.

Dies gesagt, wird die Programmausführung nie erreichen dbusA.end(), damit Signal Registrierung und Beenden der Run-Schleife wird nicht passieren. Sie können diese Methode jedoch von einem anderen Thread oder von einem Event-Handler Ihrer dbus-Verbindung aus aufrufen.