Tree.create_item() returns null

Godot Version

v4.6.stable.official [89cea1439]

Question

I’ve got simple tree that will create more children there. Unfortunately, below code does not work as “var sub_item : TreeItem = _tree.create_item(item)” returns null. I do not know why.

Tree is valid, not cleared, not empty. Metadata from item is fine, as expected. I’m checking with debugger if item is in tree (first lines of function) and it is. What;s the problem, then?

func on_item_selected() -> void:
	var item : TreeItem = _tree.get_selected()
	if (item.get_tree() != _tree) || (!is_instance_valid(item)):
		pass
	var part : Part = item.get_metadata(0) as Part
	if !part:
		GlobalAL.on_error("CarPartsPanel::on_item_activated: item= %s has null part" % [item.get_text(0)])
		return
	WBAL.show_part_details.emit(part)
	if part.part_type == Part.EPartType.SIMPLE:
		return
	var cpart : PartComplex = part as PartComplex
	for csp_arr : Array in cpart.sub_parts.values():
		for csp : PartComplex.CSubpart in csp_arr:
			var p : Part = csp.object
			if !p:
				GlobalAL.on_error("CarPartsPanel::on_item_activated: Part= %s has empty subpart object= %s" % [part.unique_id, csp.unique_id])
				return
			var sub_item : TreeItem = _tree.create_item(item)
			var item_text : String = p.item_name
			sub_item.set_text(0, item_text)
			sub_item.set_metadata(0, p)

Does the erorr still happen if you change the pass to a return :

if (item.get_tree() != _tree) || (! is_instance_valid(item)):
pass

1 Like

Yes. As I wrote above:
if (item.get_tree() != _tree) || (!is_instance_valid(item)):
pass

was just to check with debugger if item is valid. It is valid, when I change pass to return, I still get error.

I’ve also checked if item and root are in the same tree. They are.

Above function is called when I expand item, so it will add more child.
When I add above code, so it will be called when tree is created (so whole tree is created at once), it is working.

Is there some kind of “lock” on a tree that it’s leaf is being expanded?

The problem is because create_item. The first variabel isn’t for the type you at its for what is the parent. create_item(parent: TreeItem = null, index: int = -1) :link:

Creates an item in the tree and adds it as a child of parent, which can be either a valid TreeItem or null.

If parent is null, the root item will be the parent, or the new item will be the root itself if the tree is empty.

The new item will be the index-th child of parent, or it will be the last child if there are not enough siblings.

I do not understand it. create_item is called correctly:
TreeItemcreate_item(parent:TreeItem= null, index:int = -1)

And in my code item:

var item : TreeItem = _tree.get_selected()

Which returns TreeItem.

Yes but it creates a Empty Item at the Position you give it. The first value in create_item doesen’t say what should be spawned it says where it should be spawned. I am not 100 % sure but the command you probably want is void add_child(child: TreeItem) :link:

Adds a previously unparented TreeItem as a direct child of this one. The child item must not be a part of any Tree or parented to any TreeItem. See also remove_child().