Get Rect Size of a Container Node

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

Hello Everyone. I have a VBoxContainer that I add HBoxContainers to programmatically, then I add TextureButtons to the HBoxContainers, creating a grid of buttons. I would like to center the main VBoxContainer in the scene regardless of how many rows and columns are added. To do this I was hoping to get the dimensions of the VBoxContainer after adding all of the buttons and then moving it based on:

var x = (scene_x - board_x)/2
var y = (scene_y - board_y)/2
$RowContainer.set_position(Vector2(x, y))

Unfortunately everything I try returns a size of (0, 0) for the VBoxContainer. I understand by default a container node does not have a size but I thought it’s size updated after adding children. Is there someway to get the size of the container? Or is there a better way to center the container?

Thanks!

:bust_in_silhouette: Reply From: IHate

You can use a CenterContainer as a parent for the Vbox so it’s always centred.

To access the size property of a control node use rect_size.
Hovering over a property on the inspector will give you the proper method

While I can use the CenterContainer to solve my problem, I still am getting (0,0) when calling rect_size. Below is another example. In this example, I added 3 texture buttons to the VBoxContainer using the scene editor. The VBoxContainer size automatically adjusts. When I add a 4 texture button via script, I receive the same rect_size. Why is this happening?

Screenshot

aptek | 2020-10-03 03:13

Sorry for the late reply I didn’t see the post

As I understand it the entire function is happening in the same frame and the size doesn’t update until the new buttons are drawn. so what you can do is wait for the next frame to check the rect_size when the buttons are already drawn.

func _ready():
  for n in 3:
	var tButton = TextureButton.new()
	tButton.texture_normal = load("res://icon.png")
	$VBoxContainer.add_child(tButton)

  yield(get_tree(),"idle_frame") # yield until the next idle frame
  print($VBoxContainer.rect_size)

IHate | 2020-10-06 13:59