我们正在开发一个使用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
)?
答案 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事件)。
我知道这不是一个现成的解决方案,但可能是一种有用的,不同的方法。