Gtk3 Python Glade在不同窗口上的“链接”组合框

2024-05-14 08:20:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我在主窗口上有两个Gtk.Comboboxes

  • 第一,有自己的Gtk.Liststore
  • 第二个,链接到一个Gtk.TreeModelFilter,它链接到第二个Gtk.Liststore

当我在第一个选项中选择一个值时,第二个选项将根据我的选择显示值。在主窗口中效果很好。你知道吗

但在我的应用程序中,我需要多次使用这个组合框组合,当我在另一个窗口上使用它时,会生成一个我不理解的Gtk错误:

"Gtk-CRITICAL **: 00:27:38.289: gtk_tree_model_filter_set_visible_func: assertion 'filter->priv->visible_method_set == FALSE' failed"

有人能解释一下我的代码出了什么问题,错误信息是什么意思吗?你知道吗

这是林间空地档案(测试.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文件(测试.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())

先谢谢你。你知道吗


Tags: nameselfidfalsechildtrueobjectcol
1条回答
网友
1楼 · 发布于 2024-05-14 08:20:38

问题是因为主窗口上的第二个组合框和“其他”窗口上的第二个组合框使用相同的筛选器。 我已经创建了另一个过滤器,第二个组合框现在有自己的过滤器链接到一个公共Gtk.列表存储. 你知道吗

现在一切正常。你知道吗

以下是更正的文件:

林间空地一号:

<?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())

相关问题 更多 >

    热门问题