Syntax to access a control that has been added as a child to a container?

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

Using the example below: Lets say I wanted to go back and change the text on Button #50. What would be the syntax for that?

extends Control
    
onready var container = $ScrollContainer
onready var vbox = $ScrollContainer/VBoxContainer
onready var scrollbar = $ScrollContainer.get_v_scrollbar()

func _ready():
	for i in range(100):
		var btn = Button.new()
		btn.text = "Button" + str(i)
		addItem(btn)
		yield(get_tree().create_timer(.1), "timeout")

func addItem(btn):
	vbox.add_child(btn)
	yield(get_tree(), "idle_frame")
	container.scroll_vertical = scrollbar.max_value
:bust_in_silhouette: Reply From: jgodfrey

I guess it depends on what you expect to know about “Button #50” at some point in the future. That is, how do you intend to find it? For example:

  • By its text (Button 50)
  • By its index within its parent (the 50th child of the vbox)
  • Something else?

For the first option, you could just spin through the children of vbox looking for a child that is a button whose text matches “Button 50”. For the second option, you could just blindly access the 50th child of vbox.

Or, you could opt to create some kind of map between what you know and what you want to know. For instance, maybe a Dictionary with keys that are the button text (if that’s what you want to search by) and values that are the control references themselves…

So, it really depends on what you want…

What would the syntax be if you wanted to access them by index? I am trying, unsuccessfully, to do something similar and change the position and size of a TextureRect that has been added to a scroll container. I’ve tried the below without success:

var button50 = vbox.get_child(49)
button50.text = 'new value'

grymjack | 2023-06-14 22:19

What you have there should work - assuming you’re waiting until all the buttons are created (or, at least the 50th one exists)…

Works here…

jgodfrey | 2023-06-14 23:49

Here is a variant on your initial code from above. I substitute a TextureRect for the button, add it to the VBox, get the child position, and add a texture. All that works fine. But when I try and change the scale or position within the scroll container I cannot. Any thoughts?

extends Control

onready var container = $ScrollContainer
onready var vbox = $ScrollContainer/VBoxContainer
onready var scrollbar = $ScrollContainer.get_v_scrollbar()


func scroll_test():
	for i in range(3):
		var box = TextureRect.new()
		addItem(box,i)
		yield(get_tree().create_timer(.1), "timeout")

func addItem(box,i):
	vbox.add_child(box)

	# this works
	var vbox_child = vbox.get_child(i)
	var texture_path = ("res://Assets/Art/Technology/GoldFrame.jpg")
	var texture = load(texture_path) as Texture
	vbox_child.texture = texture

	# this does not work
	vbox_child.rect_scale = Vector2(0.5, 0.5)
	vbox_child.set_position(Vector2(50,50 + (i * 50)))

	yield(get_tree(), "idle_frame")
	container.scroll_vertical = scrollbar.max_value

grymjack | 2023-06-20 01:53