PyGtk:破坏组合框会导致错误
PyGtk : destroying combobox causes error
My aim is to destroy a combobox if one of its items is active.
I wrote this test code :
import pygtk
pygtk.require('2.0')
import gtk
import gobject
def remove(combobox):
if 'OptionC' in combobox.get_active_text():
combobox.destroy()
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(800, 600)
window.set_title("Test")
window.connect("destroy", gtk.main_quit)
main_box = gtk.VBox(False, 2)
window.add(main_box)
nb = 3
for i in range(nb):
liststore = gtk.ListStore(gobject.TYPE_STRING)
combo = gtk.ComboBox(liststore)
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
for text in ["OptionA-%d"%(i+1), "OptionB-%d"%(i+1), "OptionC-%d"%(i+1)]:
combo.append_text(text)
combo.set_active(0)
combo.connect("changed", remove)
main_box.pack_start(combo, expand=False)
window.show_all()
gtk.main()
If I open the popup of the combobox and click to select "OptionC", I have this message :
combo.py:29: Warning: invalid unclassed pointer in cast to `GObject' gtk.main()
combo.py:29: Warning: g_object_notify: assertion `G_IS_OBJECT (object)' failed gtk.main()
combo.py:29: Warning: g_object_set: assertion `G_IS_OBJECT (object)' failed gtk.main()
But if I select "OptionC" just scolling the combobox (without opening the popup), no error is encountered.
Thanks for your advice!
Answer : (working for pygtk version 2.24 but NOT for 2.16)
Replace this block :
liststore = gtk.ListStore(gobject.TYPE_STRING)
combo = gtk.ComboBox(liststore)
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
By this function :
combo = gtk.combo_box_new_text()
您的代码很可靠,小部件已按应有的方式销毁。只需将其记为 pygtk/PyGObject 内存管理的一个怪癖即可。
它来是因为你使用了liststore。
新的 gtk 代码现在应该使用 combo_box_new_text()
这是您的代码:
for i in range(nb):
combo = gtk.combo_box_new_text()
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
for text in ["OptionA-%d"%(i+1), "OptionB-%d"%(i+1), "OptionC-%d"%(i+1)]:
combo.append_text(text)
combo.set_active(0)
combo.connect("changed", remove)
main_box.pack_start(combo, expand=False)
window.show_all()
gtk.main()
那你为什么不使用
combobox.hide()
而不是
combobox.destroy()
看来销毁单个小部件并不是您真正应该做的事情。在大多数情况下,我不会破坏 Gtk 小部件,因为稍后您可能希望再次显示它们。
My aim is to destroy a combobox if one of its items is active.
I wrote this test code :
import pygtk
pygtk.require('2.0')
import gtk
import gobject
def remove(combobox):
if 'OptionC' in combobox.get_active_text():
combobox.destroy()
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(800, 600)
window.set_title("Test")
window.connect("destroy", gtk.main_quit)
main_box = gtk.VBox(False, 2)
window.add(main_box)
nb = 3
for i in range(nb):
liststore = gtk.ListStore(gobject.TYPE_STRING)
combo = gtk.ComboBox(liststore)
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
for text in ["OptionA-%d"%(i+1), "OptionB-%d"%(i+1), "OptionC-%d"%(i+1)]:
combo.append_text(text)
combo.set_active(0)
combo.connect("changed", remove)
main_box.pack_start(combo, expand=False)
window.show_all()
gtk.main()
If I open the popup of the combobox and click to select "OptionC", I have this message :
combo.py:29: Warning: invalid unclassed pointer in cast to `GObject' gtk.main()
combo.py:29: Warning: g_object_notify: assertion `G_IS_OBJECT (object)' failed gtk.main()
combo.py:29: Warning: g_object_set: assertion `G_IS_OBJECT (object)' failed gtk.main()
But if I select "OptionC" just scolling the combobox (without opening the popup), no error is encountered.
Thanks for your advice!
Answer : (working for pygtk version 2.24 but NOT for 2.16)
Replace this block :
liststore = gtk.ListStore(gobject.TYPE_STRING)
combo = gtk.ComboBox(liststore)
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
By this function :
combo = gtk.combo_box_new_text()
您的代码很可靠,小部件已按应有的方式销毁。只需将其记为 pygtk/PyGObject 内存管理的一个怪癖即可。
它来是因为你使用了liststore。
新的 gtk 代码现在应该使用 combo_box_new_text()
这是您的代码:
for i in range(nb):
combo = gtk.combo_box_new_text()
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
for text in ["OptionA-%d"%(i+1), "OptionB-%d"%(i+1), "OptionC-%d"%(i+1)]:
combo.append_text(text)
combo.set_active(0)
combo.connect("changed", remove)
main_box.pack_start(combo, expand=False)
window.show_all()
gtk.main()
那你为什么不使用
combobox.hide()
而不是
combobox.destroy()
看来销毁单个小部件并不是您真正应该做的事情。在大多数情况下,我不会破坏 Gtk 小部件,因为稍后您可能希望再次显示它们。