Random beginner-question: insert "text" in Label

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

Hi everyone,

I have a Label set up for entering numbers and a comma, and all works fine.
What I’m trying to do is to have a space inserted automatically between the 3rd and 4th digit. Everything in the code below works until (and including) print:

...
var preCommaCharacterCount = comma

if preCommaCharacterCount == 0:
	return false
	
var preComma
if preCommaCharacterCount == 3:
	print ("preCommaCaracters are 3 !!!!!!!!!!!!!!!!!!!")
	preComma.insert(' ')

But preComma.insert(' ') leads to the error: Invalid call. Nonexistent function 'insert' in base 'Nil'.
Is there any simple way to have that “Space” (or anything really) be inserted there?

:bust_in_silhouette: Reply From: therealguy

If I understand correctly, you can use the + operator to insert strings onto other strings like so:

preComma += ' '

For example, the following code will print “hello there!”:

var sentence = 'hello'
sentence += ' '
sentence += 'there'
sentence += '!'
print(sentence)

Thanks! Weirdly enough I get the error message Parser Error: Using assignment with operation on a variable that was never assigned., but it works when I change preComma to text

At least it almost works. Now I suddenly can’t enter anything more afterwards - the input works but nothing more is being displayed in the Label. Do you have any idea why that could be?

pferft | 2020-12-18 11:25

Oh, I believe you get that error because preComma starts out undefined, and you can’t add a string onto an undefined variable

Instead of initializing preComma without an initial value:

var preComma

You should initialize preComma to an empty string:

var preComma = ''

but I don’t know why the label won’t display any more text

therealguy | 2020-12-18 11:33

Thanks again.
Actually, my bad. I’m sorry I wasn’t clear about what I had in mind in the first place, so here is what I should have asked from the start:

What I’m trying to do is to have a space inserted automatically between the 1st and 2nd digit when the user enters a 4th one… so that e. g. 1234 appears as 1 234 (with that little gap there).

If you have any thought about this, i’d much appreciate!

pferft | 2020-12-18 12:02

Oh ok I see, I think your code then was correct except that preComma does need to be initialized to an empty string first, then you will have access to insert.

Another thing is that .insert() doesn’t modify the variable itself, it returns itself but with the insertion added.

So for this piece code:

var preComma
preComma.insert(index, ' ')

you would make these changes:

var preComma = ''
preComma = preComma.insert(index, ' ')

EDIT: sorry I forgot that the first parameter of insert is the index (a number specifying the location in the string), I fixed the code above

therealguy | 2020-12-18 12:14

Dang, almost there! Now hitting the third entry leads to the error:

Invalid call to function 'insert' in base 'String'. Expected 2 arguments.

So I guess the code demands …insert(ARGUMENT, ’ ')
Which argument could that be?

Oh, ha! Good timing! : D

Unfortunately now this happens:
Parser Error: The identifier “index” isn’t declared in the current scope.

pferft | 2020-12-18 12:20

Oof sorry, I forgot that the first parameter of insert is the index (a number specifying the location in the string)

So if you wanted to add a space after the first character, you would do:

preComma = preComma.insert(1, ' ')

therealguy | 2020-12-18 12:23

So it is “index” just as a number - you are right and I’m the one who doesn’t know…

It doesn’t crash anymore, but unfortunately doesn’t fill in anything (I tried different indexes and different ‘things’, but nothing shows). Hmm, what could be missing?

pferft | 2020-12-18 12:33

I put this code inside one of the nodes in my scene:

func _ready():
	var s = '12345'
	s = s.insert(1, 'a')
	print(s)

and it printed “1a2345” as expected

The only thing I can think of that could be going wrong is that maybe you forgot to set preComma to preComma.insert(1, ’ ') and instead just called preComma.insert(1, ’ ')?

If that isn’t the problem, you could paste in your code again, the problem might be something minor

therealguy | 2020-12-18 12:38

It works, and my preComma version prints as well.
It just doesn’t update in the Label properly, so I guess I’ll have to put in the right spot. I’ll see what I can do.
Your example helps me understand that bit better, so thanks a lot so far!

pferft | 2020-12-18 13:08

You’re welcome!

I’m not sure if this is what you mean, but when you set the text of a label, it creates a copy of the string you pass in so even if you change that string later, it won’t update automatically you’ll have to set the label’s text to the updated string every time it changes.

Here is an example of having to set the label’s text after every modification to the string

func _ready():
	var s = "12345"
	label.text = s
	s = s.insert(1, "a")
	label.text = s
	s = s.insert(2, "b")
	label.text = s

but if you do have something that looks like that, it would be better to wait until after you have done all the modifications to the string to set the label’s text like so:

func _ready():
	var s = "12345"
	s = s.insert(1, "a")
	s = s.insert(2, "b")
	label.text = s

also note that the variable “label” is not actually defined in the examples above, that’s just for where you would put your reference to the label

therealguy | 2020-12-18 13:28

Alright, it does do something, but now it replaces everything in the label instead of inserting…

pferft | 2020-12-18 13:42

label.text is a string itself, so if you wanted to insert something into the label you would do:

label.text = label.text.insert(1, 'thing')

or if you just wanted to add onto the end of the label’s text, you could do:

label.text += 'thing'

therealguy | 2020-12-18 13:46

Feeling somewhat stupid right now…

	var ggg = ""
	ggg = ggg.insert(2, "hot")
	ggg = ggg.insert(3, "cold")
	text = ggg # didn't do "label.text" - didn't work, "text" solo works...

This replaces, as mentioned before.
Now I tried

	var ggg = ""
	ggg = ggg.text.insert(2, "hot")
	ggg = ggg.text.insert(3, "cold")
	text = ggg.text

But that crashes…

pferft | 2020-12-18 14:24

Oops, sorry in one of my projects I am referencing a label from another script, but in your case you would use “text” (like you are currently) rather than “label.text” like I was saying

What I meant to say was that text is a string itself so you can insert other strings into it:

text = text.insert(1, 'thing')

and add onto the end of the text like so:

text += 'thing'

The label variable that I was talking about before is for accessing a label from another script. If you were accessing a label from another script, you would have to create a variable that holds the label node and access the text of the label node from the label variable’s .text property, but you are not accessing the label from another script, you’re programming from a script that is connected directly to the node. So where I wrote label.text in previous comments, I should have just said “text” instead of “label.text”.

So strings, like ggg in your example above, do not have a .text property, sorry if you were confused by me writing label.text, know that that was my mistake and I was thinking of a different case. There are no .text properties in any of the variables you are working with, as far as I know.

That’s why your second code example isn’t working, there is no .text property of a string

therealguy | 2020-12-18 14:52

Oh no worries! I think my knowledge about coding by now reaches about exactly that far (having to “connect to another Node” or not, in such a case, theoretically…)!

But as my first code example replaces the Label’s content rather adding to it… I just don’t know where to put the text.insert. You say my string ggg doesn’t have a text property? So I can’t insert ‘thing’ that way?

pferft | 2020-12-18 15:05

Every string has the .insert function attached to it, so you can indeed use insert on ggg by simply doing:

ggg = ggg.insert(1, 'thing')

And because text is also a string, you can access insert from text too:

text = text.insert(1, 'thing')

For your first code example, you would change it to this to make ggg be added onto the end of text:

var ggg = ""
ggg = ggg.insert(2, "hot")
ggg = ggg.insert(3, "cold")
text += ggg # it is now text += ggg rather than text = ggg

or if you wanted to, for example, insert ggg after the first character in text, you would do this:

var ggg = ""
ggg = ggg.insert(2, "hot")
ggg = ggg.insert(3, "cold")
text = text.insert(1, ggg)

therealguy | 2020-12-18 15:14

This works and teaches me about the logic behind things (need to understand where to put my ggg’s…).

What I observe it that the 2 in the second line does not really have an impact, does it?

	var ggg = ""
	ggg = ggg.insert(2, "hot")
	text = text.insert(1, ggg)

The 1 in the third line defines the insert-position.

For some reason no more input is possible after inserting “hot” in my project now, but I guess that’s something less obvious and due to its structure somehow - I’ll try to find a way around.
Anyway, thanks again for your help!

pferft | 2020-12-18 16:01