1

My question is related to PyGObject, Gtk3 and signal suppression.

I have a ComboBoxText, with a signal connected.

self.cbtPaths = Gtk.ComboBoxText()
self.cbtPaths.connect("changed", self.on_changed_path)

def on_changed_path(self,action):
    path = self.cbtPaths.get_active_text()
    i = self.hPaths.change(path)
    self.cbtPaths.set_active(i) #1

self.on_changed_path() is called when the user changes the ComboBoxText. Which is good.

on_changed_path() is called when the code carries out the line marked #1. This causes a never ending loop.

My question is: How do I prevent the line at #1 from triggering the changed signal.?

Note: I call self.cbtPaths.set_active(i) in another part of the code too.

gpoo
  • 8,408
  • 3
  • 38
  • 53
Anthony Scaife
  • 564
  • 5
  • 15
  • I don't think you want to call set_active in your on_changed_path method. on_changed_path will be called when the selection has changed so there is no need set it again. I don't understand the relationship of hPaths and cbtPaths. – ditkin Jan 01 '13 at 22:24
  • Thanks for the comment ditkin, hPaths is a helper class I wrote which populates the ComboBoxText with new items. These new items are based upon the value the user selected from the ComboBoxText. – Anthony Scaife Jan 02 '13 at 00:45

3 Answers3

2

You probably need handler_block() and handler_unblock(). The former blocks a handler of an instance to not be called during any signal emission. That handler will be blocked until you unblock it.

You can try something like:

self.cbtPaths.handler_block(self.on_changed_path)
self.cbtPaths.set_active(i)
self.cbtPaths.handler_unblock(self.on_changed_path)

You can also check GOBject API's documentation, although is a bit limited.

gpoo
  • 8,408
  • 3
  • 38
  • 53
0

Before set_active, disconnect on_changed_path from cbtPaths changed event. After set_active re-connect it.

XORcist
  • 4,288
  • 24
  • 32
0

The answer was not to fiddle with the signals at all, but for the handler to check if it should allow itself to be triggered again.

def on_cbtPaths_changed(self,action):
    if not self.hPath.is_organised(): #1
        self.hPath.organise()
    else:
        self.btnUpdate.emit("clicked") #2
    return True  

So when the user, or program, changes the ComboBoxText widget:

  • Another class modifies the contents of the ComboBoxText (#1).
  • The modification triggers the handler again.
  • This time the contents do not need modifying (#2).
  • Nothing was modified by #2 so no more signals.
Anthony Scaife
  • 564
  • 5
  • 15