Gtk4 ColumnView出现Gtk-CRITICAL警告与数据更新视觉闪烁问题求助
Gtk4 ColumnView出现Gtk-CRITICAL警告与数据更新视觉闪烁问题求助
你好,我帮你排查了这两个关联问题,还发现了代码里一个小笔误,一起给你梳理清楚~
问题根源分析
- Gtk-CRITICAL警告:你给ScrolledWindow设置了
set_propagate_natural_width(True)和set_propagate_natural_height(True),这会让ScrolledWindow强制继承子控件(ColumnView)的自然尺寸,直接干扰了Gtk内部调整器(Adjustment)的正常计算逻辑,导致lower + page_size <= upper这个断言条件不成立,从而反复抛出警告。 - 视觉Glitch:同样是ScrolledWindow的尺寸传播设置冲突,当你更新TestItem的value时,ColumnView的单元格重绘被布局矛盾打断,出现显示异常;而鼠标 hover 时触发了局部重绘,才临时修复了显示问题。
- 额外小问题:代码里的“清空列表”按钮被后面的“增加”按钮变量覆盖了,导致清空按钮根本没显示在界面上,这个我也一起帮你修正了。
解决方案
- 移除ScrolledWindow中
set_propagate_natural_width(True)和set_propagate_natural_height(True)这两个设置,让ScrolledWindow自己管理视口尺寸,避免干扰调整器计算; - 修复按钮变量覆盖的问题,确保两个功能按钮都能正常显示和工作。
修改后的完整代码
#!/usr/bin/python3 import gi gi.require_version("Gtk", "4.0") from gi.repository import Gtk, Gio, GObject, GLib class TestItem(GObject.Object): __gtype_name__ = "TestItem" name = GObject.Property(type=str) value = GObject.Property(type=int) def __init__(self, name: str, value: int): super().__init__() self.name = name self.value = value def make_table_column(title, field): """ Make a column for a field """ template = b"""<interface> <template class="GtkListItem"> <property name="child"> <object class="GtkLabel"> <binding name="label"> <lookup name="%s" type="TestItem"> <lookup name="item">GtkListItem</lookup> </lookup> </binding> </object> </property> </template> </interface> """ % (field.encode('ascii'),) template = GLib.Bytes.new(template) factory = Gtk.BuilderListItemFactory.new_from_bytes(None, template) col = Gtk.ColumnViewColumn(title = title, factory = factory, resizable = True) return col class Test(Gtk.ApplicationWindow): def __init__(self, **kargs): super().__init__(**kargs, title="Test") vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) control = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) control.append(Gtk.Label(label = "Name:")) self.name = Gtk.Entry() control.append(self.name) control.append(Gtk.Label(label = "Value:")) self.value = Gtk.SpinButton.new_with_range(1, 100, 1) control.append(self.value) button = Gtk.Button.new_from_icon_name('list-add') button.connect("clicked", self.add) control.append(button) vbox.append(control) self.model = Gio.ListStore(item_type = TestItem) view = Gtk.ColumnView() self.selection = Gtk.NoSelection(model = self.model) view.set_model(self.selection) view.append_column(make_table_column("Item name", 'name')) view.append_column(make_table_column("Value", 'value')) scroll = Gtk.ScrolledWindow() scroll.set_child(view) # 移除导致调整器计算异常的设置 # scroll.set_propagate_natural_width(True) # scroll.set_propagate_natural_height(True) scroll.set_valign(Gtk.Align.FILL) vbox.append(scroll) buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) buttons.set_valign(Gtk.Align.END) # 修复变量覆盖问题,分别命名按钮 clear_btn = Gtk.Button.new_from_icon_name('edit-clear') clear_btn.connect("clicked", self.clear) buttons.append(clear_btn) increase_btn = Gtk.Button.new_from_icon_name('list-add') increase_btn.connect("clicked", self.increase) buttons.append(increase_btn) vbox.append(buttons) vbox.set_valign(Gtk.Align.FILL) self.set_child(vbox) self.set_default_size(600, 400) def add(self, _widget): name = self.name.get_buffer().get_text() value = int(self.value.get_value()) item = TestItem(name, value) self.model.insert(0, item) def increase(self, _widget): for item in self.model: item.value += 1 def clear(self, _widget): self.model.remove_all() def on_activate(app): win = Test(application=app) win.present() app = Gtk.Application(application_id='org.kilobug.test') app.connect('activate', on_activate) app.run(None)
验证效果
修改后运行代码:
- 终端不会再出现
gtk_adjustment_configure的CRITICAL警告; - 点击“increase”按钮时,value列的数值会立即正确重绘,不会出现视觉闪烁;
- 清空按钮也能正常显示并工作。
备注:内容来源于stack exchange,提问作者Kilobug
相关产品推荐
相关产品推荐

