PyQt信号和sqlalchemy:如何正确处理对象到期

时间:2017-03-14 15:29:59

标签: python sqlalchemy pyqt

我们正在开发一个使用Qt和sqlalchemy的应用程序,并使用一个长期会话。我们从数据库加载的一些对象也很长,并且发出Qt信号以发出信号变化。为此,我们使用自定义元类的双重继承,并从@orm.reconstructor初始化QObject基类:

class LongLived(QObject, Base):
    __metaclass__ = DeclarativeQObjectMeta
    # ... column declarations ...

    something_changed = pyqtSignal(object)

    @orm.reconstructor
    def init_on_load(self):
        QObject.__init__(self)

这种方法的问题是,只要有人在对象过期后(即每次提交后)访问对象,就会调用init_on_load。然后重新初始化QObject,这似乎会终止进程中的所有信号连接。

保持PyQt信号/插槽连接到可能过期的对象的正确方法是什么(除了设置expire_on_commit=False)?

1 个答案:

答案 0 :(得分:0)

由于sqlalchemy和Qt / PyQt在处理对象生命周期方面非常特殊,因此将这两者混合起来可能并不是一个好主意。

也许您可以考虑维护一个长寿命的QObject并使用SQLAlchemy事件监听器来指示属性更改(使用SQLAlchemy example):

_qobject = None
def validate_phone(target, value, oldvalue, initiator):
    "Notify about phone number change"
    if _qobject is None:
        _qobject = YourQObjectImplementation()

    _qobject.something_changed.emit(target, value, oldvalue)
    return value

# setup listener on UserContact.phone attribute, instructing
# it to use the return value
listen(UserContact.phone, 'set', validate_phone)

你显然可以创建和存储_qobject更复杂(每个会话,每个应用程序,线程本地等),并且你必须创建所有有趣属性的监听器(您可以依次使用其他SQLAlchemy事件)。 我知道这不是一个现成的解决方案,但可能是一种有用的,不同的方法。