2015-08-06 1 views
0

Je voudrais faire quelques opérations de nettoyage à l'intérieur de l'objet juste avant sa destruction. Dans ce cas, ce serait la connexion à la base de données.Comment appeler une fonction lorsqu'un QObject est sur le point d'être détruit?

Voici ce que je fais déjà:

classe des travailleurs:

from PyQt5 import QtCore 
from pymongo import MongoClient, ASCENDING 
from time import sleep 

class StatusWidgetWorker(QtCore.QObject): 

    ongoing_conversions_transmit = QtCore.pyqtSignal([list]) 

    def __init__(self, mongo_settings): 
     super().__init__() 
     print("StatusWidget Worker init") 
     mongo_client = MongoClient([mongo_settings["server_address"]]) 
     self.log_database = mongo_client[mongo_settings["database"]] 
     self.ongoing_conversions = mongo_settings["ongoing_conversions"] 

    def status_retriever(self): 
     print("mongo bridge()") 
     while True: 
      ongoing_conversions_list = [] 
      for doc in self.log_database[self.ongoing_conversions].find({}, {'_id': False}).sort([("start_date", ASCENDING)]): 
       ongoing_conversions_list.append(doc) 
      self.ongoing_conversions_transmit.emit(ongoing_conversions_list) 
      sleep(2) 

Et la fonction qui appelle le travailleur d'une autre classe:

def status_worker(self): 
    mongo_settings = "dict parameter" 

    self.worker_thread_status = QtCore.QThread() 
    self.worker_object_status = StatusWidgetWorker(mongo_settings) 
    self.worker_object_status.moveToThread(self.worker_thread_status) 

    self.worker_thread_status.started.connect(self.worker_object_status.status_retriever) 
    self.worker_object_status.ongoing_conversions_transmit.connect(self.status_table_auto_updater) 

    self.worker_thread_status.start() 

Voici ce que je déjà essayé:

  • Define a __del__ function dans la classe Worker, cette fonction n'est jamais appelée.
  • Définissez une fonction dans la classe Worker, puis connectez-la au signal détruit avec self.destroyed.connect(self.function). Cette fonction n'est encore jamais appelée. Je pense que cela arrive parce que le signal est émis quand l'objet est déjà détruit, pas avant sa destruction.

Je me demande vraiment comment cela, voici quelques parties de réponse:

http://www.riverbankcomputing.com/pipermail/pyqt/2014-November/035049.html

Son approche semble un peu hacky pour moi (pas d'infraction à l'auteur, il est probablement pas de réponse simple) et j'ai des signaux à transmettre à l'opérateur, ce qui rendrait la classe ThreadController plus désordonnée.

-je trouver cette solution un peu hacky parce que vous devez mettre en place une classe de contrôleur pour faire le travail de la classe des travailleurs

Si personne n'a une réponse, je vais probablement utiliser la classe ThreadController et post ici le résultat.

Merci de lire :-)

+0

La réponse à la question dans votre titre est de se connecter au [ 'QObject.destroyed'] (http://doc.qt.io/qt-5/qobject.html #destroyed). Je ne comprends pas pourquoi vous considérez cette solution "hacky". Pourriez-vous élaborer? –

+0

a modifié ma question, il devrait être clair maintenant – icefo

+0

Hmm, avez-vous essayé de connecter le signal détruit à une fente dans le fil lui-même, ou un dans le fil principal? –

Répondre

0

La règle habituelle en python appliquer:

il existe un module pour cette

la solution est d'utiliser le module atexit et inscrivez-vous la fonction de nettoyage dans la fonction __init__.

Exemple:

import atexit 

class StatusWidgetWorker(QObject): 

    def __init__(self): 
     super().__init__() 
     # code here 
     atexit.register(self.cleanup) 

    def cleanup(self): 
     print("Doing some long cleanup") 
     sleep(2) 
     self.bla = "Done !" 
     print(self.bla)