How to call a func by clicking a text inside a RichTextLabel?

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

Hi!
I’m having a problem with assigning a function to clickable text inside of a RichTextLabel. My label is bbcode enabled. I’m able to get the text to be underlined and clickable by doing this:

label.bbcode_text = '[url="function_to_call"]Clickable text[/url]' 

But then I get stuck. I know there is a meta_clicked signal that this emits but I can’t get it to work. I want function_to_call() to be called when the clickable text between url tags is clicked. What is the correct syntax?

You mean something like that?

extends RichTextLabel

func _ready():
	bbcode_enabled = true
	bbcode_text = '[url="function_to_call"]Clickable text[/url]'

func _on_RichTextLabel_meta_clicked(meta):
	function_to_call()

func function_to_call():
	print("Label has been clicked!")

juppi | 2020-05-27 18:24

Doesn’t work. Also, why would you need this:

func _on_RichTextLabel_meta_clicked(meta):
    function_to_call()

This to me looks like an auto generated function when connecting meta_clicked in the editor. This will not work for me as I am assigning the text from a remote script and the function I want to call is also in that remote script.

Macryc | 2020-05-27 18:46

OK here’s what i ended up doing and it worked:

func _ready():
	label.connect("meta_clicked", self, "label_clicked") 

func some_other_func():
	label.bbcode_text = '[url="do_something"]Clickable text[/url]'

func label_clicked(do_something):
	do something

Macryc | 2020-05-27 18:50

:bust_in_silhouette: Reply From: aXu_AP

This is a bit old question, but it popped up in search and I didn’t find other answers, so…
meta_clicked signal calls the function you connect it to and passes defined url as a parameter as a string (also note, write string without quotation marks). So we need to use that parameter to decide what to call. Thankfully godot has call function, which takes function name as a parameter.
The solution is to connect signal to call function:

extends RichTextLabel

func _ready() -> void:
	bbcode_text = "[url=print_hello]Click me![/url]"
	# This is the crucial bit. connect signal to call function.
	connect("meta_clicked", self, "call")

func print_hello():
	print("Hello world!")

Notice, that any function can be called from text this way, so don’t use text from external sources (user input, file)!
If you want to be on safe side, you can make a custom handler function which runs logic in a match statement, for example:

extends RichTextLabel

func _ready() -> void:
	bbcode_text = "[url=print]Print something[/url] or [url=quit]quit[/url]."
	connect("meta_clicked", self, "handle")

func handle(argument):
	match argument:
		"print": print("Hello world!")
		"quit": get_tree().quit()