Connect getting TypeError with 'activate' signal when using Gio.SimpleAction

I am receiving the following error when using any of the following ‘connect’ formats:

TypeError: second argument must be callable
remove_action.connect('activate', self.remove_link(iter), iter)
remove_action.connect('activate', self.remove_link(iter=iter), iter)
remove_action.connect('activate', self.remove_link(iter))

However, what is interesting is that the ‘remove_link’ call actually succeeds as well as passing the ‘iter’ parameter as expected.

The function call is this:
def remove_link(self, iter):

Is there a problem with Gio or is there a problem with Python understanding what should be callable and what is not?

Python 3.11.2
gir1.2-glib-2.0:amd64 1.74.0-3

My python is rusty, but I don’t think that is how you pass lambdas/functions.

I think you are passing the string 'activate', the return value of self.remove_link(link) and - in the first two variants - iter. That is, the remove_link() method is called when connecting the signal, not when the signal is actually emitted.

2 Likes

The correct format is:

remove_action.connect('activate', self.remove_link, iter)

I am not sure why you would think passing ‘link’ as a parameter would make a difference without seeing the code for that function. I can assure you ‘iter’ is necessary. I can also assure you that the remove_link() method is not called upon executing the ‘connect’. I know this because of logging. I can see exactly when this method is called and it is most certainly during button press events.

Sorry, but, in my case, you would be wrong. That syntactical method ends up not calling remove_link() at all. I would prefer that syntactical method if it worked. In the cases I mentioned in my first post the method is actually called but with a TypeError. And I can see that from logging. But, when I use you proposed method I see no logging event within the remove_link() method.

The following statement was copied from online documentation:
“If an incorrect type is given when activating the action, this signal is not emitted.”

I suspect that is why I am not seeing the remove_link() method executing.

If I was to use Gtk.Action in place of Gio.SimpleAction then I can use this which works perfectly and without any error:

item.connect('activate', lambda o: self.remove_link(iter=iter))

The name of that variable isn’t material, and I’m sure they didn’t intend to imply otherwise.

Their explanation was correct: you are in fact executing the method when you connect to the signal.

You need to provide a callable with the correct signature for the signal, as in:

def on_remove_activated(self, action, parameter, iter):
    self.remove_link(iter)

[...]

remove_action.connect('activate', self.on_remove_activated, iter)

Alternatively, you can use a lambda:

remove_action.connect('activate', lambda *a: self.remove_link(iter))

I know that is not correct. And the reason I know that is that I would see a logging message at the time the ‘connect’ is executed and I do not see that happening. I only see the function being executed when I right-click the Link.

“def on_remove_activated(self, action, parameter, iter):”

Ok, now that works.

I assume the called function was not being called because of this:

“If an incorrect type is given when activating the action, this signal is not emitted.”

Actually this documentation comment is not complete enough in that it should say something about the called function being formed properly.

I know that ‘activate’ takes two parameters: Gio.SimpleAction and GLib.Variant or None.

I assumed that the ‘iter’ parameter could be passed in place of the GLib.Variant. That appears not to be the case. As you point out the function needs 4 parameters and not 3.

I had tried this in the past (obviously without success):
def remove_link(self, action, param)

Again, a BIG problem with the lack of clear documentation.

Is there some way for me to add to the Gnome documentation so as to be clear for novices like myself? I am sure there are lots more of us novices than there are of you guys.

Optional additional signal handler parameters are a PyGObject feature, documented here: https://lazka.github.io/pgi-docs/#GObject-2.0/classes/Object.html#GObject.Object.connect

Yes, I remember reading that, but, I guess it went right over my head after reading so many other bits of documentation previously. I can’t say why, at the time, I did not pay closer attention to that. My aging brain maybe.

I think maybe the confusion was that what I had read about ‘activate’ and the two parameters it mentioned, took precedence in my thinking.

In looking at this closer I see the problem. I had tried adding the ‘iter’ parameter to the ‘connect’ statement and it did not work. I knew that the ‘activate’ method took 2 parameters and I assumed that the connected function would take those two parameters as well. What I was not getting is that the the 3rd parameter (iter) that was added to the ‘connect’ function would be passed as an extra parameter to the connected function (in addition to what ‘activate’ passes). I think that is why I assumed that ‘iter’ would take the place of the ‘param’ parameter.

Merge requests are welcome. The documentation you were referring to is here: gio/gsimpleaction.c · ea58dcb53820f82fb991b086ece6440e4b0e1c94 · GNOME / GLib · GitLab

My problem with that documentation is that it is incomplete and does not offer any examples of how to integrate the functions into a workable app. That documentation was written by the Gnome developers. Their perspective on programming can be quite different from us neophytes. They understand things about the code that we do not and as a result they make assumptions that leave us in the dark.

For example this:

" /**

  • GSimpleAction:parameter-type:
  • The type of the parameter that must be given when activating the action.
    "
    What types can these parameters be?

As well, this function: g_simple_action_set_enabled

From the description provided one would think that all you have to do is enable this and the action would be available for use. It does not mention anything about the fact that there are other settings that are necessary as well. For example, that the prefix needs to be the same when using ‘bind_model()’ and with ActionGroup and MenuItems.

My point is that unless a complete picture is formed a person can consume huge amounts of time floundering around and trying to come up with a workable solution.

This is why there are so many questions being asked on various forums of how to proper implement a specific solution or why something doesn’t work as they were expecting it to work and after reading what documentation is available.

When the Gnome developers produce a function they have in mind the way that the function is to be used (i.e., how that function is to be used with other functions to produce something workable). That conceptual thinking is seldom conveyed when documentation is written about how a specific function operates.And that is very necessary information for the rest of us.

It’s all open source, so please do submit a merge request with some improvements to the documentation. FOSS software is not written by some distant cabal of experts, it’s written by everyone who uses it. As you’ve explained, you’re in a good position to see what documentation is missing or could be expanded. Thanks!