get_visible_line_count() returning the previous state of the label even after I change the label's text.

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

If I try to get the number of lines from the same function that the richTextLabel’s text was changed. It’s as if the label’s visible text is not the value that i am changing, this value is only changed after the function Itself and get_visible_line_count() gets its value from this non-directly alterable value.

	LineCountLabel.text = "text"
    #linecount = 0 and not 1 even though i just changed the text
    var lineCount = LineCountLabel.get_visible_line_count() 

How can i work around this? I need to get this value before i open the text box so i can determine its required height.

:bust_in_silhouette: Reply From: Zylann

It still prints 0 of it starts with 5 lines of text… that looks like a bug.
There is an open issue RichText: get_visible_line_count() returns wrong value · Issue #18722 · godotengine/godot · GitHub

Maybe you could use get_content_height() after having set the text, which is more like what you want.

But even then, both these functions only work after the text has been drawn at least once, which means you have to wait one frame with the text visible to get the height.
I guess you want to know that before showing that text. In which case, you could ALSO do a feature request, or report it as bug xD

If you considered line count to determine text height, I assume you are not planning to use any size-changing BBCode?
If yes and none of the options above suit you, you could do something like this:

len(text.split("\n", true))

If you actually don’t need any BBCode, you could use Label instead, which resizes itself automatically.

I am now trying to delay the function by 1 frame after the text is set in order for it to render since i’m using a textbox off screen to get these values so it doesn’t matter if they appear for a split second but the function ( GetLinesHeight() ) just seems to end after i try to delay it by one frame after setting the text.

I’m guessing that the function “just ends” since nothing in my function prints after:

yield(get_tree(), "idle_frame")

or alternatively

yield(VisualServer, 'frame_post_draw')

The value returned by the function doesn’t print anything so i don’t know what this value is but when it gets divided by 2 later on my code throws an error "Invalid Operands ‘Object’ and ‘int’ in operator ‘/’ ". maybe it’s an object then?

when i call GetLinesHeight() to get it’s value from somewhere else like var height = GetLinesHeight(BoxInstance,width,text) why doesn’t the function i’m calling GetLinesHeight() from wait to get the value before continuing?

How do i ensure that a value is returned?

KnightNine | 2019-09-07 01:15

I’m not sure what’s going on here. What do you mean by GetLinesHeight() “just ends”? It’s a getter, it returns one integer value. If you get nothing or an object it means your code is wrong somehow.
I imagine it would need to just be this:

# Before that is the code that need the height
yield(get_tree(), "idle_frame")
var height = get_lines_height()
# Use the height

If you wrap this in a function though, it becomes a bit harder, I don’t remember how to use yield in that situation. if your code is structured by function calls, introducing a yield is quite a drastic change to how the call flow should execute, because it makes it asynchronous. i.e it won’t complete immediately.

This shows that being able to measure the height of a RichTextLabel before showing it is quite needed and ugly to workaround. It should be fixed IMO.
In the meantime, using Label or counting \n characters is easier I think.

Zylann | 2019-09-07 01:29

GetLinesHeight() is basically what you mean by wrapping it in a function. it is delayed and asynchronous from the functions trying to use it due to containing yield().

I’m not sure how i would use yield in that situation either and that’s what I’m trying to figure out, when you remember let me know if you can.

Does it have something to do with emitting a custom signal after the delay? Or does
var height = GetLinesHeight() complete on it’s own without letting GetLinesHeight() complete? Meaning that height continues with the mystery glitched object of an incomplete function and will remain that way even if a yield was placed after var height = GetLinesHeight() to make the functions synchronous again.

I’ll just dump everything in the same function for now, hopefully I don’t encounter any issues.

KnightNine | 2019-09-07 02:44

I figured it out btw, to get the returned value out of a function assigned to a var while waiting for it to complete at the same time you can do: height = yield(functionThatReturnsHeight(),"completed")

KnightNine | 2019-09-11 03:33