在主窗口中我有两个Gtk.Comboboxes
:
Gtk.Liststore
Gtk.TreeModelFilter
,第二个Gtk.Liststore
链接到当我在第一个中选择一个值时,第二个将根据我的选择显示值。这在主窗口中效果很好。
但是在我的应用程序中,我需要多次使用此组合框组合,并且当我在另一个窗口中使用它时,这会生成我不理解的Gtk错误:
“ Gtk-CRITICAL **:00:27:38.289: gtk_tree_model_filter_set_visible_func:断言 'filter-> priv-> visible_method_set == FALSE'失败”
有人可以向我解释我的代码有什么问题,以及该错误消息的含义是什么
这是林间空地文件(test.ui)
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">1</col>
<col id="1" translatable="yes">fruits</col>
</row>
<row>
<col id="0" translatable="yes">2</col>
<col id="1" translatable="yes">colors</col>
</row>
</data>
</object>
<object class="GtkListStore" id="liststore2">
<columns>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">10</col>
<col id="1" translatable="yes">lemon</col>
</row>
<row>
<col id="0" translatable="yes">11</col>
<col id="1" translatable="yes">apple</col>
</row>
<row>
<col id="0" translatable="yes">12</col>
<col id="1" translatable="yes">strawberry</col>
</row>
<row>
<col id="0" translatable="yes">20</col>
<col id="1" translatable="yes">blue</col>
</row>
<row>
<col id="0" translatable="yes">21</col>
<col id="1" translatable="yes">yellow</col>
</row>
<row>
<col id="0" translatable="yes">22</col>
<col id="1" translatable="yes">purple</col>
</row>
</data>
</object>
<object class="GtkTreeModelFilter" id="filter">
<property name="child_model">liststore2</property>
</object>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<signal name="destroy" handler="on_quit" swapped="no"/>
<child>
<placeholder/>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">20</property>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Open other</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_other" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">20</property>
<property name="margin_right">20</property>
<property name="row_spacing">5</property>
<property name="column_spacing">10</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkComboBox" id="w1_combo1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">liststore1</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="w1_combo2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">filter</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo1</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkDialog" id="window2">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window1</property>
<child>
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btn_close">
<property name="label" translatable="yes">Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_left">20</property>
<property name="margin_right">20</property>
<property name="margin_top">20</property>
<property name="margin_bottom">20</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_top">20</property>
<property name="margin_bottom">20</property>
<property name="vexpand">True</property>
<property name="row_spacing">5</property>
<property name="column_spacing">10</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkComboBox" id="w2_combo1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">liststore1</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="w2_combo2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">filter</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo1</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-7">btn_close</action-widget>
</action-widgets>
</object>
</interface>
和python文件(test.py):
#!/usr/bin/env python3
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import sys
class Main:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file('test.ui')
self.builder.connect_signals(self)
self.obj = self.builder.get_object
self.window = self.obj('window1')
self.combo1 = self.obj('w1_combo1')
self.combo2 = self.obj('w1_combo2')
self.combo1.connect('changed', self.on_select, self.combo2)
self.filter = self.obj('filter')
self.filter.set_visible_func(self.filter_func)
self.combo1_val = None
self.window.show()
def on_other(self, btn):
Other(self.obj)
def on_select(self, combo, next_combo):
self.combo1_val = combo.get_active_id()
self.filter.refilter()
next_combo.set_active(0)
def filter_func(self, model, iter, data):
if self.combo1_val is None: return True
else: return self.combo1_val == model[iter][0][:1]
def on_quit(self, widget):
Gtk.main_quit()
class Other:
def __init__(self, obj):
self.obj = obj
self.window = self.obj('window2')
self.combo1 = self.obj('w2_combo1')
self.combo2 = self.obj('w2_combo2')
self.combo1.connect('changed', self.on_select, self.combo2)
self.filter = self.obj('filter')
self.filter.set_visible_func(self.filter_func)
self.btn_close = self.obj('btn_close')
self.btn_close.connect('clicked', self.on_hide)
self.combo1_val = None
self.window.show()
def on_select(self, combo, next_combo):
self.combo1_val = combo.get_active_id()
self.filter.refilter()
next_combo.set_active(0)
def filter_func(self, model, iter, data):
if self.combo1_val is None: return True
else: return self.combo1_val == model[iter][0][:1]
self.window.show()
def on_hide(self, btn):
self.window.hide()
def main():
app = Main()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
谢谢。
答案 0 :(得分:0)
问题是由于以下事实:主窗口上的第二个组合框和“其他”窗口上的第二个组合框正在使用相同的过滤器。 我创建了另一个过滤器,第二个组合框现在有自己的过滤器,这些过滤器链接到一个通用的Gtk.Liststore。
现在一切正常。
以下是更正的文件:
一个空地:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">1</col>
<col id="1" translatable="yes">fruits</col>
</row>
<row>
<col id="0" translatable="yes">2</col>
<col id="1" translatable="yes">colors</col>
</row>
</data>
</object>
<object class="GtkListStore" id="liststore2">
<columns>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">10</col>
<col id="1" translatable="yes">lemon</col>
</row>
<row>
<col id="0" translatable="yes">11</col>
<col id="1" translatable="yes">apple</col>
</row>
<row>
<col id="0" translatable="yes">12</col>
<col id="1" translatable="yes">strawberry</col>
</row>
<row>
<col id="0" translatable="yes">20</col>
<col id="1" translatable="yes">blue</col>
</row>
<row>
<col id="0" translatable="yes">21</col>
<col id="1" translatable="yes">yellow</col>
</row>
<row>
<col id="0" translatable="yes">22</col>
<col id="1" translatable="yes">purple</col>
</row>
</data>
</object>
<object class="GtkTreeModelFilter" id="w1_filter">
<property name="child_model">liststore2</property>
</object>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<signal name="destroy" handler="on_quit" swapped="no"/>
<child>
<placeholder/>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">20</property>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Open other</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_other" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">20</property>
<property name="margin_right">20</property>
<property name="row_spacing">5</property>
<property name="column_spacing">10</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkComboBox" id="w1_combo1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">liststore1</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="w1_combo2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">w1_filter</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo1</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkTreeModelFilter" id="w2_filter">
<property name="child_model">liststore2</property>
</object>
<object class="GtkDialog" id="window2">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window1</property>
<child>
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btn_close">
<property name="label" translatable="yes">Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_left">20</property>
<property name="margin_right">20</property>
<property name="margin_top">20</property>
<property name="margin_bottom">20</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_top">20</property>
<property name="margin_bottom">20</property>
<property name="vexpand">True</property>
<property name="row_spacing">5</property>
<property name="column_spacing">10</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkComboBox" id="w2_combo1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">liststore1</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="w2_combo2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">w2_filter</property>
<property name="active">0</property>
<property name="id_column">0</property>
<property name="active_id">0</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo1</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Combo2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-7">btn_close</action-widget>
</action-widgets>
</object>
</interface>
还有一个python:
#!/usr/bin/env python3
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import sys
class Main:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file('test.ui')
self.builder.connect_signals(self)
self.obj = self.builder.get_object
self.window = self.obj('window1')
self.combo1 = self.obj('w1_combo1')
self.combo2 = self.obj('w1_combo2')
self.combo1.connect('changed', self.on_select, self.combo2)
self.filter = self.obj('w1_filter')
self.filter.set_visible_func(self.filter_func)
self.combo1_val = None
self.window.show()
def on_other(self, btn):
Other(self.obj)
def on_select(self, combo, next_combo):
self.combo1_val = combo.get_active_id()
self.filter.refilter()
next_combo.set_active(0)
def filter_func(self, model, iter, data):
#print(self.combo1_val, model[iter][0][:1])
if self.combo1_val is None: return True
else: return self.combo1_val == model[iter][0][:1]
def on_quit(self, widget):
Gtk.main_quit()
class Other:
def __init__(self, obj):
self.obj = obj
self.window = self.obj('window2')
self.combo1 = self.obj('w2_combo1')
self.combo2 = self.obj('w2_combo2')
self.combo1.connect('changed', self.on_select, self.combo2)
self.filter = self.obj('w2_filter')
self.filter.set_visible_func(self.filter_func)
self.btn_close = self.obj('btn_close')
self.btn_close.connect('clicked', self.on_hide)
self.combo1_val = None
self.window.show()
def on_select(self, combo, next_combo):
self.combo1_val = combo.get_active_id()
self.filter.refilter()
next_combo.set_active(0)
def filter_func(self, model, iter, data):
#print(self.combo1_val, model[iter][0][:1])
if self.combo1_val is None: return True
else: return self.combo1_val == model[iter][0][:1]
self.window.show()
def on_hide(self, btn):
self.window.hide()
def main():
app = Main()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())