You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide2中QObject子类Property设置notify后属性变更未触发信号

问题解决方案

根因说明

Qt的Property声明中传入的notify参数仅用于向Qt元对象系统注册「该属性变更时会触发对应信号」的关联关系,框架本身不会自动在属性赋值时帮你发射信号,信号发射逻辑需要你手动添加到属性的setter方法中。
这个设计是Qt的原生通用逻辑,并非PySide2的缺陷:即使是C++版本的Qt开发,声明Q_PROPERTY的NOTIFY字段后,同样需要开发者手动在setter中发射对应信号。

修改方案

你只需要在属性的_set_p setter方法中,更新属性值后手动发射p_changed信号即可,推荐同时增加新旧值判断逻辑,避免值未变更时触发无效信号:

from PySide2.QtCore import QObject, Property, Slot, Signal


class A(QObject):
    p_changed = Signal()

    def __init__(self):
        super(A, self).__init__()
        self._p = 0

    def _get_p(self):
        print(f"Getting p (val: {self._p})")
        return self._p

    def _set_p(self, v):
        # 新旧值一致时不做更新和信号触发,减少无效开销
        if self._p == v:
            return
        print(f"Setting new p: {v}")
        self._p = v
        # 手动发射属性变更通知信号
        self.p_changed.emit()
    p = Property(int, _get_p, _set_p, notify=p_changed)


if __name__ == "__main__":
    import sys
    from PySide2.QtWidgets import QApplication, QWidget

    app = QApplication([])


    class W(QWidget):
        def __init__(self, *args):
            super().__init__(*args)
            self.a = A()
            self.a.p_changed.connect(self.test_slot)

            print(self.a.p)
            self.a.p = 42
            # 此时会正常打印"Got notified"
            print(self.a.p)

        @Slot()
        def test_slot(self):
            print("Got notified")


    w = W()
    w.show()
    sys.exit(app.exec_())

修改完成后运行代码,给属性p赋值时就会自动触发关联的p_changed信号,执行绑定的槽函数。

内容的提问来源于stack exchange,提问作者zeeMonkeez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 04:09:01