How to reference a variable or property of a node

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

I’m trying to use signals connected by code. In my case here’s an example:

#Here, the value of $Textline.text is "bar"
func _ready():
    $Button.connect("pressed",self,"print_textline_text",[$Textline.text]

print_textline_text(message):
     print("the message is" + str(message))

Right now if I click the button, the function will print “bar”, everything it’s normal, but, if I change the value during runtime, to “foo”, and click the button, the fuction will print “bar” again. As it took the value that the $Textline.text when the _ready() method was called.

So what I need is a way to reference the property and not the value. So when the signal gets triggered, it will take the current value and not the one that was there in the _ready call.

The example is just to give some context, my current project needs, to reference that property and I can’t simply put it inside the fuction as it has to be dynamic. I don’t want to have extra variables running around to pass a dynamic value, because it’s quite probable that there is a way to do it but I don’t know how.

:bust_in_silhouette: Reply From: Inces

You should use NodePath type for this signal. Check it in documentation and You will learn how to contruct nodepaths leading to properties.

But…
Why won’t You just bind value while emitting signal instead of while connecting ? If you would pass text on emitting it will always be actual

How do I emit the signal if it is a button? Isn’t it automatically emitted without the chance of passing binds?

MaximoTG98 | 2021-03-15 21:36

It is, there are several ways around this. I usually do one script for buttons and make custom button press. Still it requires scripting the button, but I never knew about expression class as in other answer below, It sounds like more elegant sollution.

Inces | 2021-03-16 16:03

:bust_in_silhouette: Reply From: Jayman2000

You could use an Expression.

#Here, the value of $Textline.text is "bar"
func _ready():
    var expression = Expression.new()
    var expression_text = 'get_node("Textline").text'
    var err = expression.parse(expression_text)

    if err == OK:
        $Button.connect(
                "pressed",
                self,
                "print_textline_text",
                [expression]
        )
    else:
        push_warning(
                'Failed to parse "%s" as an expression. Error: %s'
                % [expression_text, expression.get_error_text()]
        )


func print_textline_text(expression):
    var message = expression.execute([], self)
    if expression.has_execute_failed():
        push_warning(
                "Failed to execute expression %s."
                % [expression]
        )
    else:
        print("the message is " + str(message))

Okay it took me some days and many re-reads to understand what was happening since the docs are really incomplete with Expressions. But wow, this is amazing. I need to learn more about this, it’s so powerful. Thanks!

MaximoTG98 | 2021-03-17 23:37