How do I hyperlink certain text in a text widget? (tkinter)

for item_name i’m trying to hyperlink it to my robloxItemLink variable so that the text is a clickable link. here’s my code:

for item_id, item_info in items.items():
    item_name = item_info[0]
    item_value = item_info[3]
    item_rarity = item_info[9]

    if item_value != -1 and min_value <= item_value <= max_value:
        rarity_text = "Yes" if item_rarity == 1 else "No"
        robloxItemLink = f"https://www.roblox.com/catalog/{item_id}"

        text_widget.insert(
            'end',
            (
                f"{item_name}\n"
                f"• Value: {item_value:,}\n"
                f"• Rare: {rarity_text}\n\n"
            )
        )

Hello,

I don’t think that you have to do anything special. The document that you are writing the text to should auto-recognize that it is a link. I am currently creating a .pdf document which includes writing a url. When I open the document, and hover my mouse over it, it recognizes that it is a link and the mouse pointer which is an arrow, automatically turns into a hand, implying that it is a link.

The same should work if you’re creating a Word, Excel, etc., document.

Here is a small script. It will create a document and it will save it to your desktop for easy referencing. Note that I did not do anything special.

import os
os.chdir(r'C:\Desktop')

from fpdf import FPDF

# Prepare PDF generator
pdf = FPDF(orientation = 'P', unit = 'mm', format = 'letter') # Set format and unit
pdf.add_page()

# Write to page
pdf.set_font(family='arial', size=12, style='')
pdf.set_y(100)
pdf.set_x(100)
pdf.cell(w=0, txt='www.python.org', align='L')

# # Output the PDF
pdf.output("url_test.pdf")

hey Paul,
thanks very much for your help! your code was very insightful. i’m going to use it to learn python. thank you!

the thing is is that i’m making some sort of program in VS code and my text in my text widget is selectable and stuff. i’m not very experienced with python so i’m not sure where to look.

this is what i think i need to:

I misundertood (misread) your problem. I thought you wanted to know how to write text (which happens to be a link), to a document, and make it clickable.

From the first quote above, do you mean that you want to be able to “click” the variable item_name and have it take you to the url that robloxItemLink is assigned to? Can you elaborate further please. This will help with the second quote.

1 Like

my apologies if I wasnt clear.

yes exactly as u said. where u see item_name, i want that to be clickable

        text_widget.insert(
            'end',
            (
                f"{item_name}\n"
                f"• Value: {item_value:,}\n"
                f"• Rare: {rarity_text}\n\n"
            )
        )

Interesting.

As currently written, is the following true:

item_name = "The Void Star"  # Is this what 'item_name' is currently assigned to?... a string

I did a search for “add clickable text to tkinter Text widget” and among others it came up with the result Tkinter Text Widget With Example - python-hub where there’s an example under the heading " Embedding Links (Sort of)"

hope this helps

2 Likes

Good catch @avisser :wink:

@target , here is a test script :

Here is a slightly modified test script from the link that @avisser provided. You have to import the webbrowser library package to make it work. The call back function includes the action of opening the url of your choice. You can edit it as per your project requirements (for testing purposes, I included www.python.org). I am using Windows 11. To open the link, you have to simultaneously press the CTRL key when clicking the variable item_name.

import tkinter as tk
import webbrowser

root = tk.Tk()
root.title("Text Widget Demo")
root.geometry("400x300")

text = tk.Text(root)
text.pack(pady=20, padx=20)

def clicked(event):

    webbrowser.open('www.python.org')

item_name = "The Void Star"

text.insert("1.0", item_name)
text.tag_add("link", "1.0", "1.10")
text.tag_config("link", foreground="blue", underline=False)
text.tag_bind("link", "<Button-1>", clicked)

root.mainloop()

Hope this works for you.

1 Like

@avisser @onePythonUser

perfect job! that was exactly what i was looking for. thank you both so much for your help. :slight_smile:

for anyone looking for how i did it, here’s a quick demo:

# by @targetdior
import tkinter as tk
import webbrowser

window_width = 750
window_height = 500

# window stuff
window = tk.Tk()
window.update_idletasks()
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x = (screen_width // 2) - (window_width // 2)
y = (screen_height // 2) - (window_height // 2)
window.geometry(f"{window_width}x{window_height}+{x}+{y}")
window.title("Embedded Link Test")

# text widget w/ scroll bar
text_frame = tk.Frame(window)
text_frame.pack(fill='both', expand=True, padx=10, pady=10)
scrollbar = tk.Scrollbar(text_frame)
scrollbar.pack(side='right', fill='y')
text_widget = tk.Text(text_frame, yscrollcommand=scrollbar.set, bg='black', fg='red', font=("Arial", 40))
text_widget.pack(fill='both', expand=True)
scrollbar.config(command=text_widget.yview)

# clicked event
def clicked(event):
        webbrowser.open(link)
    # print("link clicked")

# insert text
TextString = "yo click here lil bro >:)"
link = "https://i.giphy.com/VVezdkhLTHwkM.webp"
text_widget.insert("end", TextString + "\n")

# tag for the link styling
text_widget.tag_add("link", "1.0", f"1.{len(TextString)}")
text_widget.tag_config("link", foreground="blue", underline=False)
text_widget.tag_bind("link", "<Button-1>", clicked)

# tag for center alignment of the entire line
text_widget.tag_add("center", "1.0", "1.end")
text_widget.tag_config("center", justify="center")

# make it so that you can't type in the text widget (read only)
text_widget.config(state="disabled")

window.mainloop()
1 Like

You can make your life a little bit easier by using the .index method to determine the start and end positions of the link text:

start = text.index(tk.INSERT)
text.insert(tk.INSERT, "The clickable text")
end = text.index(tk.INSERT)
text.tag_add("link", start, end)
1 Like

thanks very much man, i’ll use that trick! :slight_smile: