Gtk 如何使用Python进行双向数据绑定+;PyGObject';s GObject.bind_属性函数?

Gtk 如何使用Python进行双向数据绑定+;PyGObject';s GObject.bind_属性函数?,gtk,pygobject,gobject,Gtk,Pygobject,Gobject,这个问题的背景(以及我的总体目标)是以一种良好的方式构造Python GTK应用程序。我正在尝试使用将小部件属性绑定到模型属性 我的期望是双向绑定应该使两个属性保持同步。相反,我发现更改只向一个方向传播,即使我使用的是GObject.BindingFlags.BIDIRECTIONAL标志。我创建了下面的最小示例和失败的测试用例test\u widget\u syncs\u to\u model,以说明问题。请注意,在更现实的示例中,模型对象可以是Gtk.Application的实例,小部件对象

这个问题的背景(以及我的总体目标)是以一种良好的方式构造Python GTK应用程序。我正在尝试使用将小部件属性绑定到模型属性

我的期望是双向绑定应该使两个属性保持同步。相反,我发现更改只向一个方向传播,即使我使用的是
GObject.BindingFlags.BIDIRECTIONAL
标志。我创建了下面的最小示例和失败的测试用例
test\u widget\u syncs\u to\u model
,以说明问题。请注意,在更现实的示例中,模型对象可以是
Gtk.Application
的实例,小部件对象可以是
Gtk.Entry
的实例

导入gi
gi.require_版本('Gtk','3.0')
从gi.repository导入Gtk,GObject
导入单元测试
对象类(GObject.Object):
“”“具有'txt'属性的非常简单的GObject。”“”
name=“默认值”
txt=GObject.Property(type=str,default=“default”)
定义初始化(self,name,*args,**kwargs):
super()
self.name=名称
self.connect(“通知”,self.log)
def日志(自身、源、参数名称):
印刷品(
“{self.name}”对象收到通知事件
f“它的txt现在是{self.txt}”
)
类TestBindings(unittest.TestCase):
def设置(自):
“”“在模型和小部件之间设置双向绑定”“”
打印(f“\n\n{self.id()}”)
self.model=Obj(“model”)
self.widget=Obj(“widget”)
self.model.bind_属性(
“txt”,self.widget,“txt”,flags=GObject.BindingFlags.com
)
@单元测试跳过(“成功”)
找到def测试属性(自身):
“”“验证是否正确设置了'txt'属性。”“”
对于[self.model,self.widget]中的obj:
self.assertsnotnone(obj.find_属性(“txt”))
@单元测试跳过(“成功”)
def test_model_同步_到_小部件(self,data=“hello”):
“”“验证模型更改是否传播到小部件”“”
self.model.txt=数据
self.assertEqual(self.widget.txt,数据)
def test_widget_与_模型同步(self,data=“world”):
“”“验证小部件更改是否传播回模型”“”
self.widget.txt=数据
self.assertEqual(self.widget.txt,数据)#成功
self.assertEqual(self.model.txt,数据)#失败
如果名称=“\uuuuu main\uuuuuuuu”:
unittest.main()
上述程序输出:

ssF
======================================================================
FAIL: test_widget_syncs_to_model (__main__.TestBindings)
Verifies that widget changes propagate back into the model
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/jh/.config/JetBrains/PyCharmCE2021.1/scratches/scratch_14.py", line 52, in test_widget_syncs_to_model
    self.assertEqual(self.model.txt, data)  # FAILS
AssertionError: 'default' != 'world'
- default
+ world


----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (failures=1, skipped=2)


__main__.TestBindings.test_widget_syncs_to_model
The 'widget' object received a notify event, its txt now is 'world'.

Process finished with exit code 1
我的具体问题是,如何让双向数据绑定工作?。。。如果有人能修改我的例子或提供另一个有效的例子,我会很高兴


从更广泛的意义上讲,双向绑定是在结构良好的Python GTK应用程序中同步UI状态和模型状态的方法吗?打算用什么样的方式来实现这一点?谢谢

更改
txt
属性时是否会发出信号?属性绑定依赖于
notify
信号来工作。谢谢!我在代码示例中添加了日志记录。这似乎表明接收到的通知信号的文本值“txt”错误。我认为您实际上希望在
log()
函数中打印
print(“received notify event”,self.txt)
param
参数实际上是一个
GParamSpec
实例,它描述属性类型,但不描述其当前值。因此,我认为正在打印的
txt
实际上只是属性名称。注意:我在中发布了一个指向此问题的链接,因为我非常确定GNOME社区会有答案。嗨!谢谢菲利普的帮助和关心!Zander Brown善意地指出了GNOME对话线程中我的代码中的错误:设置绑定时必须将标志作为位置参数传递。您或Zander想在这里提供关于stackoverflow的答案吗?