Why can't Godot find and call this method?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By RaebaldKashban

Hi all. I’m trying to get a simple plugin working but ran into a “method not found” error. Some background below.

The concept of the plugin is straightforward: I want a panel to appear when the user presses a key; then, I want the user to be able to close the panel by clicking a button. Here’s the code that is meant to achieve this:

The plugin code:

tool
extends EditorPlugin

var dialogue_editor_window_path = "res://addons/DialogueEditor/DialogueEditorWindow.tscn"

func _enter_tree():
	InputMap.add_action("open_dialogue_editor")
	var new_input_event = InputEventKey.new()
	new_input_event.set_scancode(KEY_Q)
	InputMap.action_add_event("open_dialogue_editor", new_input_event)
	
func _exit_tree():
	InputMap.erase_action("open_dialogue_editor")
	
func _input(event):
	if event.is_action_pressed("open_dialogue_editor"):
		var dialogue_editor_window = load(dialogue_editor_window_path).instance()
		dialogue_editor_window.get_node("Button").connect("pressed",dialogue_editor_window,"_on_button_pressed")
		add_child(dialogue_editor_window)

The code for the panel that will be displayed.

extends Panel

func _on_button_pressed():
	queue_free()

The panel scene itself is very simple–just a Panel node with a single Button as a child. The code above works for getting the panel opened, but when I click the “Close” button, I get the following error:

 core/object.cpp:1260 - Error calling method from signal 'pressed': 'Panel(DialogueEditorWindow.gd)::_on_button_pressed': Method not found..

For some reason, the “pressed” signal doesn’t find the target method in the panel’s script, but it’s clearly there as far as I can tell. My assumption is that there’s something screwy going on here with the way that tools/editor plugins work, but I’m honestly at a loss. What’s strange is that Godot doesn’t complain when I try to connect the “pressed” signal to the method–doesn’t it usually do this if the method doesn’t exist?

Would appreciate any ideas you have. Thanks!

:bust_in_silhouette: Reply From: Magso

If i’m understanding this correctly you’re using the connect method the wrong way round. You’re currently connecting a signal that doesn’t exist on dialogue_editor_window to the button instead of connecting the button pressed signal to dialogue_editor_window.
Here it is the other way round

dialogue_editor_window.connect("pressed", dialogue_editor_window.get_node("Button"), "_on_button_pressed")

Thanks for your reply, Magso. I tried your suggestion and connected signals the other way around. Code now looks like this:

dialogue_editor_window.connect("pressed",dialogue_editor_window.get_node("Button"),"_on_Button_pressed")

Unfortunately, it didn’t do the trick. I now get the following error.

In Object of type 'Panel': Attempt to connect nonexistent signal 'pressed' to method 'Button._on_Button_pressed'.

I’m pretty sure I had it the right way around before. As far as I understand it, if you want to connect a signal to a method, you need to call .connect() on the node that will be emitting the signal. So if I have a button that I want to connect to a panel, I would do something like

button.connect("pressed", panel, "_on_button_pressed")

And then I’d want to make sure that the method “_on_button_pressed” exists in the panel’s script.

At this point, I suspect the issue has something to do with the way signals work when extending the EditorPlugin class. Either this is a bug with Godot or I’m still missing something.

Thanks for taking a look.

RaebaldKashban | 2020-09-27 00:21

You’re right, I got confused which node the script was on and gave it you the wrong way round :/. However if signals aren’t working the workaround is to add a node to root with a specific name and use get_node_or_null to check if it exists and call a function of it does. This is like a node based way of how signals work.

Magso | 2020-09-27 10:32