【问题标题】:How to call a function when a QObject is about to be destroyed?QObject即将被销毁时如何调用函数?
【发布时间】:2015-10-28 23:24:48
【问题描述】:

我想在对象销毁之前对其内部进行一些清理操作。在这种情况下,它将关闭与数据库的连接。

这是我已经在做的事情:

工人阶级:

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)

以及从其他类调用工作者的函数:

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

这是我已经尝试过的:

  • Define a __del__ function 在 Worker 类中,这个函数永远不会被调用。
  • 在 Worker 类中定义一个函数,然后用self.destroyed.connect(self.function) 将其连接到被破坏的信号。这个函数再也不会被调用。我认为这是因为信号是在对象已经被销毁时发出的,而不是在它被销毁之前。

我真的很想知道如何做到这一点,以下是部分答案:

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

他的方法对我来说似乎有点老套(作者无意冒犯,可能没有简单的答案),而且我有信号和参数要传递给工人女巫会使 ThreadController 类更混乱。

我觉得这个解决方案有点 hacky,因为你必须设置一个 Controller 类来完成 Worker 类的工作

如果没有人有答案,我可能会使用 ThreadController 类并将结果发布在这里。

感谢您的阅读:-)

【问题讨论】:

  • 标题中问题的答案是连接QObject.destroyed信号。我不明白您为什么认为该解决方案“hacky”。你能详细说明一下吗?
  • 编辑了我的问题,现在应该清楚了
  • 嗯,您是否尝试将被破坏的信号连接到线程本身的插槽,或主线程中的插槽?
  • 我试图将它连接到线程本身的一个插槽,因为我想关闭这个线程打开的数据库连接。
  • 我仍然有点惊讶,没有工作。最后一个问题,您是在__init__ 方法还是status_retriever 方法中连接到被破坏的信号?前者将在主线程中建立连接,而后者应在线程本身中建立连接。如果线程在主线程处理信号时被销毁,我不会感到惊讶,但是如果信号在同一个线程中调用插槽并且应该在对象被销毁之前发出该信号,则应该立即处理信号。

标签: python destructor pyqt5 qobject


【解决方案1】:

python 中的常用规则适用:

有一个模块

解决办法是使用atexit模块,在__init__函数中注册清理函数。

例子:

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)

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 2012-01-30
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多