python - PyGTK's GtkComboBox.clear_all() is very slow -


in python script (using glade interface building) have few comboboxes regularly re-populated options change.

this works fine when list of options short, 10 or so. can longer, 100 options no exception. problem clearing list slow, takes 10 seconds during program hangs on specific line.

here fragment of code, combobox cleared using remove_all() , filled again using append_text(). i've done simple tests , found out it's second line, remove_all() call, culprit. rest of code runs fast.

    # clear combobox     self.add_tour_selector.remove_all()      # populate combobox.     ids = [t['id'] t in self.tours]     in sorted(ids):         self.add_tour_selector.append_text(i)      self.add_tour_selector.set_active(0) 

i'm looking ways drastically speed up. having wait script start responding again long no fun. these comboboxes have repopulated time well, it's hard try keep track of changing options , updating it.

the add_tour_selector taken glade file this:

        self.add_tour_selector = self.builder.get_object('add_tour_selector') 

printing gives <comboboxtext object @ 0x7f3bdcb1b870 (gtkcomboboxtext @ 0x2ba22a0)>

the comboboxtext populated this:

    # populate combobox.     ids = [t['id'] t in self.tours]     in sorted(ids):         self.add_tour_selector.append_text(i)      self.add_tour_selector.set_active(0) 

one particularly slow 1 (with lots of entries - @ least 100 - comboboxtext object) populated this:

    # clear combobox     self.bookings_tour_selector.remove_all()      # populate tour selector.     self.bookings_tour_selector.append('0', 'all')      s in self.schedule:         d = s['datetime'].strftime('%d/%m')         self.bookings_tour_selector.append(str(s['number']), '%s %s'% (d, s['tourid'])) 

the remove_all() function slow, rest of code fast.

gtkcombobox.remove_all calls (internally) liststore.clear(), there little benefit replacing comboboxtext combobox + model.

however, 10 seconds clear 100 elements list sounds incredibly slow. debugging (and timing) these things not easy do. widgets convert 2 parts when used: 'command' part, , 'graphic' part, graphic part executed asynchronously - converted code executed when main loop of program idle. so, possible remove_all triggering series of graphics commands earlier in program, slow.

also, depends if have defined list sorted - sorting tends quite slow.

finally, speed depend on if have defined renderering process complicated.

here's simple example remove_all instantaneous (as far can see). i've set number of elements 1000 - it's 'fill' noticeably slow, because updates graphics in each loop:

#!/usr/bin/env python # -*- coding: utf-8 -*- # #  test_remove_all.py #   #  copyright 2015 john coppens <john@jcoppens.com> #   #  program free software; can redistribute and/or modify #  under terms of gnu general public license published #  free software foundation; either version 2 of license, or #  (at option) later version. #   #  program distributed in hope useful, #  without warranty; without implied warranty of #  merchantability or fitness particular purpose.  see #  gnu general public license more details. #   #  should have received copy of gnu general public license #  along program; if not, write free software #  foundation, inc., 51 franklin street, fifth floor, boston, #  ma 02110-1301, usa. #   #     gi.repository import gtk  class mainwindow(gtk.window):     def __init__(self):         super(mainwindow, self).__init__()         self.connect("destroy", lambda x: gtk.main_quit())         self.set_size_request(200, -1)          self.clear_btn = gtk.button("clear")         self.clear_btn.connect("clicked", self.clear_btn_clicked)         self.add_btn = gtk.button("add 100")         self.add_btn.connect("clicked", self.add_btn_clicked)         self.label = gtk.label("0 elements")         self.combo = gtk.comboboxtext()         self.add_btn_clicked(self)          self.vbox = gtk.vbox()         self.vbox.pack_start(self.clear_btn, false, true, 0)         self.vbox.pack_start(self.add_btn, false, true, 0)         self.vbox.pack_start(self.label, false, true, 0)         self.vbox.pack_start(self.combo, false, true, 0)          self.add(self.vbox)         self.show_all()      def clear_btn_clicked(self, btn):         self.combo.remove_all()      def add_btn_clicked(self, btn):         n in range(100):             self.combo.append_text("string %d" % n)          self.combo.set_active(1)         model = self.combo.get_model()         self.label.set_text("%d elements" % model.iter_n_children(none))      def run(self):         gtk.main()   def main(args):     mainwdw = mainwindow()     mainwdw.run()      return 0  if __name__ == '__main__':     import sys     sys.exit(main(sys.argv)) 

click add 100 several times, clear - it's fast. in fact, tried till several 1000s. @ 1000s, things slow.


Comments