Why is the draw area cleared after a signal has been processed?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By bmer
:warning: Old Version Published before Godot 3 was released.

I have a Container node, which has two child nodes.

One child is a Container node, call it “Display”, the other is a LineEdit node, call it “InputBar”.

Display and InputBar are connected, since in the _ready method of InputBar I have:

connect("enter_hit", get_node("/root/Display"), "display_input")

enter_hit is a custom signal, which is emitted when the Return key is pressed after something is typed in InputBar (InputBar is set to process events):

func _input(event):
	if (event.type == InputEvent.KEY):
		if event.scancode == KEY_RETURN:
			emit_signal("enter_hit", get_text())
			get_tree().set_input_as_handled()
			clear() 

Display then does this:

func _draw():
	draw_string(custom_font, top_right, display_string)
	
func display_input(input_text):
	display_string = input_text
	update()

When I run the scene, the following happens:

1) I type something into InputBar, like “Hello World!”

2) I hit Enter, and then InputBar clears, and “Hello World!” shows up briefly in the display, before disappearing

3) return to 1) if more stuff is typed

So it seems the signal is emitted and handled properly, but then why does the draw area of Display immediately get cleared? At first I thought it might be an issue with _draw, so what I did instead was instantiate a Label node inside Display, and all I would do to process the input text is update the text of the Label — this time I would need no _draw calls. Still though, the same thing happens! Why?

Major breakthrough: the clear() call in the _input method for InputBar is the “issue”. If I replace it with set_text(""), the issue still persists. So, I need to “copy” the text somehow (so that the text variables are actually separate variables, and not “reflections”/pointer-connected), but I don’t know how…

bmer | 2017-06-25 13:27

:bust_in_silhouette: Reply From: Zylann

It happens because there are in fact two key events: press and release.
You aren’t checking this, so your code will get executed for both. You clear the text in the first, but then when you release the key the text is still empty but you indirectly trigger update again, which will draw an empty string.

The fix would then be:

func _input(event):
    if event.type == InputEvent.KEY and event.pressed:
        if event.scancode == KEY_RETURN:
            emit_signal("enter_hit", get_text())
            get_tree().set_input_as_handled()
            clear() 

do I also have to check for is_echo?

bmer | 2017-06-27 16:19