我正在寻找在格式化后自动将 GObject 变量写入小部件的最佳方法。例如,限制小部件中显示的实数变量的小数位数。
我认为这通常可以使用函数
bind_property_with_closures()
或bind_property_full()
来完成,但只有bind_property()
可用。
现在我找到了解决方法,首先使用
bind_property()
将实际变量写入隐藏的小部件。然后将它从隐藏的小部件绑定到可见的小部件,同时使用我的 python 函数修改它float_with_2_digits()
。
#!/usr/bin/python3
import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Adw, Gtk, Gio, Gdk, GLib, GObject
xml = """\
<interface>
<template class="example2" parent="GtkBox">
<property name="spacing">12</property>
<property name="margin-top">12</property>
<property name="margin-end">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<child>
<object class="GtkLabel" id='my_hidden_label'>
<property name="visible">FALSE</property>
</object>
</child>
<child>
<object class="GtkLabel">
<binding name="label">
<closure type='gchararray' function='float_with_2_digits'>
<lookup name="label">my_hidden_label</lookup>
</closure>
</binding>
</object>
</child>
</template>
</interface>
"""
class Article(GObject.Object):
price = GObject.Property(type=float)
def __init__(self, price):
super().__init__()
self.price = price
@Gtk.Template(string=xml)
class MyBox(Gtk.Box):
__gtype_name__ = "example2"
my_label = Gtk.Template.Child("my_hidden_label")
@Gtk.Template.Callback()
def float_with_2_digits(self, my_box, real1):
real3=""
if real1:
real2=float(real1.replace(',','.'))
real3=f'{real2:.2f}'
print("real1=<%s> => real3=<%s>" % (real1,real3))
return real3
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
article = Article(0)
# unknown: article.bind_property_with_closures
# not implemented: article.bind_property_full
article.bind_property("price",
self.my_label, "label",
GObject.BindingFlags.SYNC_CREATE)
article.price=1.6666
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
my_box = MyBox()
self.set_child(my_box)
class MyApp(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.connect('activate', self.on_activate)
def on_activate(self, app):
self.win = MainWindow(application=app)
self.win.present()
app = MyApp(application_id="de.bschu.expression2")
app.run(sys.argv)
解决方法是通过 UI 模板中定义的闭包来完成。 解决方法正在发挥作用。 但我想知道是否有更好的方法。你如何解决这个问题?
如果没有更好的解决方法,我希望至少我的解决方法对其他人有用。
您可以在链接中阅读:https://gitlab.gnome.org/GNOME/pygobject/-/issues/628
您不需要完整/封闭变体 bind_property() 接受可选的transform_to/from 可调用对象 它相当于 def bind_property(self, source_property, target_obj, target_property, flags=GObject.BindingFlags.DEFAULT, transform_to=None, transform_from=None)