Accidentally broke my button functionality

Godot Version

4.2.1 Stable

Question

I somehow broke the functionality of my buttons. I was trying to sort all my Nodes into something like folders and before settling on putting them in a Canvas Group, I ended up putting them in a container and a separate node and I think at some point in moving stuff on the hierarchy, I’ve caused a disconnect somewhere.

The full script is here, but the relevant part of my script is as follows:


func _ready():
	
	print(ButtonBox.get_children())  #Output displayed below
	
	for button in ButtonBox.get_children():
		if button is Button:
			button.pressed.connect(_on_button_pressed.bind(button)) #Throws an error, but only one, see below
			var test = button.is_connected("pressed", _on_button_pressed)
			print("\r" + button.name + "connected: " + str(test))
	
func _on_button_pressed(buttonPressed):
	print(buttonPressed.name)	#Never get any output from this.


And when I check the console output afterward, I get this:


[LoadFile:<Button#45734692215>, SaveFile:<Button#45785023866>, Help:<Button#45835355517>, Credits:<Button#45885687168>, WindowLabel:<RichTextLabel#45936018819>]

LoadFileconnected: true

SaveFileconnected: true

Helpconnected: true

Creditsconnected: true

With one error in the Debugger tab – but just one, not one per iteration. It points to the line the .connect() is on:


E 0:00:00:0823   TheScript.gd:35 @ _ready(): Signal 'pressed' is already connected to given callable 'Control(TheScript.gd)::_on_button_pressed' in that object.
  <C++ Error>    Method/function failed. Returning: ERR_INVALID_PARAMETER
  <C++ Source>   core/object/object.cpp:1358 @ connect()
  <Stack Trace>  TheScript.gd:35 @ _ready()
 

I’m testing on my Load File button, which has the pressed() signal set to the on_button_pressed() function. But I swore that I had to actually turn that off at some point, because I kept getting an error that it was trying to call on_button_pressed with 0 arguments instead of 1. But also, in the Node tab of the Inspector, it has: pressed() =green arrow thing=> ../../.. :: _on_button_pressed() and I swear it didn’t need to escape up three paths before. But maybe I just didn’t notice it.

Signals cam break if you move nodes around. I would look at nodes emitting signals in the signal inspector tab and re connect each one. :sweat:

Part of it was probably that, but in the end I think what really did me in was the “layering” of things in the hierarchy. Once I set the background to…ignore? pass? Whatever I had to do with the mouse settings, then the buttons were at least clickable.

Then I still couldn’t get them to behave so I just left well enough alone and just have everything under the main Control node, it’s a very small, single-purpose project and I probably spent more time just trying to organize my nodes than actively coding.

First of all, I’m not quite sure what your question is here.

But knowing how your scene tree looks would certainly help!

If you get the error just once, that likely means you connected one of the buttons from the editor (in the “Node” tab) as well. Since you cannot connect the same signal to the same callback multiple times, you get an error when trying to do so a second time in your _ready function.

That merely depends on where your Button is located relative to the script with the callback you’re connecting it to. If the script were attached to the button itself it would be . :: _on_button_pressed(), if it were attached to the button’s parent node it would be `… :: _on_button_pressed()" and so on.

Again, this entirely depends on your scene tree, but it’s possible for a Control node to be in front of another and consuming the mouse input, yes. In that case, you have to either re-arrange the order of your Control nodes, or make sure mouse_filter is not set to MOUSE_FILTER_STOP