如何向tkinter输出文本添加超链接。

huangapple go评论82阅读模式
英文:

How to add hyperlink to a tkinter output text

问题

我正在使用tkinter控制台创建用户输入,机器人根据用户输入提供一定的指令集作为输出。在这些指令中,我需要一个网站的链接,以便用户点击它时能在新的浏览器标签中打开,但不确定如何实现。有人可以帮忙吗?

    from datetime import datetime
    from tkinter import *
    import tkinter as tk
    from tkinter import messagebox
    from PIL import ImageTk, Image
    import webbrowser
    from tkinter import scrolledtext
    
    root = tk.Tk()
    
    now = datetime.now()
    current_date_time = now.strftime("Welcome to my world! - %Y-%m-%d %H:%M:%S")
    title_text = "Welcome to my world ! - {}".format(current_date_time)
    root.title(title_text)
    
    root.geometry("500x400")  
    root.configure(bg="#D22730")
    
    # 处理用户输入并生成机器人响应的函数
    def get_bot_response():
        user_input = input_box.get("1.0", tk.END).strip().lower()
        output_box.configure(state='normal')  # 启用编辑输出框
        output_box.insert(tk.END, 'User: {}\n'.format(user_input))
    
        # 检查用户查询并相应地提供指示
    
        if 'expense report in fusion tool' in user_input or 'expense report' in user_input:
            instructions = "要在Fusion工具中创建费用报告,请按照以下步骤进行:\n\n"
            instructions += "1. 使用您的凭据登录Fusion工具 **https://www.fusiontool.com**\n"
            instructions += "2. 导航到 'Expense' 部分。\n"
            instructions += "3. 点击 'Create New Expense Report' 或类似选项。\n"
            instructions += "4. 填写必填信息,如费用项目、金额、日期等。\n"
            instructions += "5. 附上任何相关的收据或支持文件。\n"
            instructions += "6. 核对费用报告的准确性。\n"
            instructions += "7. 提交费用报告以供审批。\n\n"
          
    
            response = instructions
    
        else:
            response = "抱歉,我无法理解您的查询。您能重新表达一下吗?"
    
        output_box.insert(tk.END, 'Bot: {}\n'.format(response))
        output_box.see(tk.END)  # 滚动输出框以显示最新的
    
    
    
    input_box = scrolledtext.ScrolledText(root, width=60, height=5, font=("Arial", 12))
    input_box.pack()
    
    
    output_box = scrolledtext.ScrolledText(root, width=60, height=10, font=("Arial", 12))
    output_box.configure(state='disabled')  # 禁用编辑输出框
    output_box.pack()
    
    
    submit_button = Button(button_frame, text="提交", command=get_bot_response)
    submit_button.pack(side=LEFT)
    
    root.mainloop()
英文:

I am creating a user input using tkinter console for which the bot gives certain set of instructions as output based on user input, in those set of instructions i need a link of website so that if the users click on it, it should get open in a new browser tab but not sure how can i do it ? can anyone please help ?

from datetime import datetime
from tkinter import *
import tkinter as tk
from tkinter import messagebox
from PIL import ImageTk, Image
import webbrowser
from tkinter import scrolledtext
root = tk.Tk()
now = datetime.now()
current_date_time = now.strftime("%Y-%m-%d %H:%M:%S")
title_text = "Welcome to my world ! - {}".format(current_date_time)
root.title(title_text)
root.geometry("500x400")  
root.configure(bg="#D22730")
# Function to handle user input and generate bot response
def get_bot_response():
user_input = input_box.get("1.0", tk.END).strip().lower()
output_box.configure(state='normal')  # Enable editing the output box
output_box.insert(tk.END, 'User: {}\n'.format(user_input))
# Check user queries and provide instructions accordingly
if 'expense report in fusion tool' in user_input or 'expense report' in user_input:
instructions = "To create an expense report in Fusion Tool, please follow these 
steps:\n\n"
instructions += "1. Log in to Fusion Tool using your credentials **https:\\www.fusiontool.com**\n"
instructions += "2. Navigate to the 'Expense' section.\n"
instructions += "3. Click on 'Create New Expense Report' or similar option.\n"
instructions += "4. Fill in the required details such as expense items, amounts, 
dates, etc.\n"
instructions += "5. Attach any relevant receipts or supporting documents.\n"
instructions += "6. Review the expense report for accuracy.\n"
instructions += "7. Submit the expense report for approval.\n\n"
response = instructions
else:
response = "Sorry, I didn't understand your query. Can you please rephrase it?"
output_box.insert(tk.END, 'Bot: {}\n'.format(response))
output_box.see(tk.END)  # Scrolls the output box to show the latest
input_box = scrolledtext.ScrolledText(root, width=60, height=5, font=("Arial", 12))
input_box.pack()
output_box = scrolledtext.ScrolledText(root, width=60, height=10, font=("Arial", 12))
output_box.configure(state='disabled')  # Disable editing the output box
output_box.pack()
submit_button = Button(button_frame, text="Submit", command=get_bot_response)
submit_button.pack(side=LEFT)
root.mainloop()

答案1

得分: 1

    # 在 main.py 中的代码片段

    from tkHyperlinkManager import HyperlinkManager
    from functools import partial

    # ...

    hyperlink = HyperlinkManager(output_box)

    # ...

    output_box.insert(tk.END, user_input,
                      hyperlink.add(partial(webbrowser.open,
                                            input_box.get("1.0", tk.END).strip().lower())))

    # ...

    # 在 tkHyperlinkManager.py 模块中的代码片段

    class HyperlinkManager:

        def __init__(self, text):
            # ...

        def add(self, action):
            # ...

        def _click(self, event):
            for tag in self.text.tag_names(CURRENT):
                if tag[:6] == "hyper-":
                    self.links[tag](event)
                    return
英文:

> How to add hyperlink to a tkinter output text
>
> I need a link of website so that if the users click on it, it should
> get open in a new browser tab but not sure how can I do it.

In main.py.

  • I add two modules from tkHyperlinkManager import HyperlinkManager
    and from functools import partial.
  • In line 27, I add parameter for output_box.insert(...
  • In line 54, I add callbackcallback(url) function.
  • In line 65, create instance for hyperlink=
    HyperlinkManager(output_box)

Snippet:

from datetime import datetime
from tkinter import *
import tkinter as tk
from tkinter import messagebox
from PIL import ImageTk, Image
import webbrowser
from tkinter import scrolledtext
from tkHyperlinkManager import HyperlinkManager
from functools import partial
root = tk.Tk()
now = datetime.now()
current_date_time = now.strftime("%Y-%m-%d %H:%M:%S")
title_text = "Welcome to my world ! - {}".format(current_date_time)
root.title(title_text)
root.geometry("500x400")  
root.configure(bg="#D22730")
# Function to handle user input and generate bot response
def get_bot_response():
user_input = input_box.get("1.0", tk.END).strip().lower()
print(user_input)
output_box.configure(state='normal')  # Enable editing the output box
#output_box.insert(tk.END, 'User: {}\n'.format(user_input))
output_box.insert(tk.END, user_input,
hyperlink.add(partial(webbrowser.open,
input_box.get("1.0", tk.END).strip().lower())))
# Check user queries and provide instructions accordingly
if 'expense report in fusion tool' in user_input or 'expense report' in user_input:
instructions = "To create an expense report in Fusion Tool, please follow these \
steps:\n\n"
instructions += "1. Log in to Fusion Tool using your credentials **https:\\www.fusiontool.com**\n"
instructions += "2. Navigate to the 'Expense' section.\n"
instructions += "3. Click on 'Create New Expense Report' or similar option.\n"
instructions += "4. Fill in the required details such as expense items, amounts, \
dates, etc.\n"
instructions += "5. Attach any relevant receipts or supporting documents.\n"
instructions += "6. Review the expense report for accuracy.\n"
instructions += "7. Submit the expense report for approval.\n\n"
response = instructions
else:
response = "Sorry, I didn't understand your query. Can you please rephrase it?"
output_box.insert(tk.END, '\n Bot: {}'.format(response))
output_box.see(tk.END)  # Scrolls the output box to show the latest
def callback(url):
webbrowser.open_new_tab(url)
input_box = scrolledtext.ScrolledText(root,  width=60, height=5, font=("Arial", 12))
input_box.pack()
output_box = scrolledtext.ScrolledText(root, width=60, height=10, font=("Arial", 12))
output_box.configure(state='disabled')  # Disable editing the output box
output_box.pack()
hyperlink= HyperlinkManager(output_box)
submit_button = Button(root, text="Submit", command=get_bot_response)
submit_button.pack(side=LEFT)
root.mainloop()

In tkHyperlinkManager.py module.

Snippet:

from tkinter import *
class HyperlinkManager:
def __init__(self, text):
self.text = text
self.text.tag_config("hyper", foreground="blue", underline=1)
self.text.tag_bind("hyper", "<Enter>", self._enter)
self.text.tag_bind("hyper", "<Leave>", self._leave)
self.text.tag_bind("hyper", "<Button-1>", self._click)
self.reset()
def reset(self):
self.links = {}
def add(self, action):
# add an action to the manager.  returns tags to use in
# associated text widget
tag = "hyper-%d" % len(self.links)
self.links[tag] = action
return "hyper", tag
def _enter(self, event):
self.text.config(cursor="hand2")
def _leave(self, event):
self.text.config(cursor="")
def _click(self, event):
for tag in self.text.tag_names(CURRENT):
if tag[:6] == "hyper-":
self.links[tag](event)
return

Screenshot:

如何向tkinter输出文本添加超链接。

Just click link and will to you to page.

Another screesnhot:

如何向tkinter输出文本添加超链接。

答案2

得分: 1

根据Text.insert()文档:

pathName insert index chars ?tagList chars tagList ...?

在索引之前插入所有chars参数。如果索引引用文本的末尾(最后一个换行符之后的字符),则新文本将插入在最后一个换行符之前。如果只有一个chars参数且没有tagList,则新文本将接收插入点之前和之后字符上的所有标签;如果标签仅存在于这些字符中的一个上,则不会应用于新文本。如果指定了tagList,则它由标签名称列表组成;新字符将接收此列表中的所有标签,而不管插入点周围存在的标签如何。如果存在多个chars-tagList参数对,它们产生与为每对发出单独的pathName insert小部件命令相同的效果,按顺序执行。最后的tagList参数可以省略。

这意味着你可以为要插入的字符串指定标签,如下所示:

output_box.insert(tk.END, "前往 ", "", "http://www.google.com", "url", ...)

上面的示例将为超链接分配标签"url"。

以下是修改后的get_bot_response()

# 处理用户输入并生成机器人回复的函数
def get_bot_response():
    user_input = input_box.get("1.0", tk.END).strip().lower()
    output_box.configure(state='normal')  # 启用编辑输出框
    output_box.insert(tk.END, '用户: {}\n'.format(user_input))

    # 检查用户查询并相应提供说明

    if '在Fusion工具中创建费用报告' in user_input or '费用报告' in user_input:
        instructions = ["要在Fusion工具中创建费用报告,请按照以下步骤进行:\n\n"]
        # 为超链接分配标签"url"
        instructions += [["1. 使用您的凭据登录到Fusion工具 ", "", "https://www.python.org", "url", "\n"]]
        instructions += ["2. 导航到'费用'部分。\n"]
        instructions += ["3. 单击'创建新费用报告'或类似选项。\n"]
        instructions += ["4. 填写所需的详细信息,如费用项目、金额、日期等。\n"]
        instructions += ["5. 附加任何相关的收据或支持文件。\n"]
        instructions += ["6. 审查费用报告以确保准确性。\n"]
        instructions += ["7. 提交费用报告以进行批准。\n\n"]

        response = instructions

    else:
        response = ["抱歉,我不理解您的查询。您能重新表述一下吗?"]

    output_box.insert(tk.END, '机器人: ')
    for line in response:
        if type(line) is list:
            output_box.insert(tk.END, *line)
        else:
            output_box.insert(tk.END, line)
    output_box.see(tk.END)  # 滚动输出框以显示最新内容
    output_box.configure(state="disabled")

然后,你需要绑定鼠标点击事件到标签上,使用 webbrowser.open() 打开超链接:

output_box = scrolledtext.ScrolledText(root, width=80, height=10, font=("Arial", 12))
output_box.configure(state='disabled')  # 禁止编辑输出框
output_box.pack()

def open_link(event):
    # 获取鼠标点击位置的索引
    current = output_box.index(f"@{event.x},{event.y}")
    # 查找鼠标点击下的超链接
    ranges = list(output_box.tag_ranges("url"))
    for start, end in zip(ranges[::2], ranges[1::2]):
        if output_box.compare(start, "<=", current) and output_box.compare(current, "<", end):
            url = output_box.get(start, end)
            webbrowser.open(url)
            break

output_box.tag_bind("url", "<1>", open_link)
output_box.tag_config("url", foreground="blue", underline=1)
英文:

According to the document of Text.insert():

pathName insert index chars ?tagList chars tagList ...?<br/>

> Inserts all of the chars arguments just before the character at index.
> If index refers to the end of the text (the character after the last
> newline) then the new text is inserted just before the last newline
> instead. If there is a single chars argument and no tagList, then the
> new text will receive any tags that are present on both the character
> before and the character after the insertion point; if a tag is
> present on only one of these characters then it will not be applied to
> the new text. If tagList is specified then it consists of a list of
> tag names; the new characters will receive all of the tags in this
> list and no others, regardless of the tags present around the
> insertion point. If multiple chars-tagList argument pairs are present,
> they produce the same effect as if a separate pathName insert widget
> command had been issued for each pair, in order. The last tagList
> argument may be omitted.

It means that you can specify the tag for a string being inserted, like:

output_box.insert(tk.END, &quot;go to &quot;, &quot;&quot;, &quot;http://www.google.com&quot;, &quot;url&quot;, ...)

The above example will assign tag "url" to the hyperlink.

Below is the modified get_bot_response():

# Function to handle user input and generate bot response
def get_bot_response():
    user_input = input_box.get(&quot;1.0&quot;, tk.END).strip().lower()
    output_box.configure(state=&#39;normal&#39;)  # Enable editing the output box
    output_box.insert(tk.END, &#39;User: {}\n&#39;.format(user_input))

    # Check user queries and provide instructions accordingly

    if &#39;expense report in fusion tool&#39; in user_input or &#39;expense report&#39; in user_input:
        instructions = [&quot;To create an expense report in Fusion Tool, please follow these steps:\n\n&quot;]
        # assign tag &quot;url&quot; to the hyperlink
        instructions += [[&quot;1. Log in to Fusion Tool using your credentials &quot;, &quot;&quot;, &quot;https://www.python.org&quot;, &quot;url&quot;, &quot;\n&quot;]]
        instructions += [&quot;2. Navigate to the &#39;Expense&#39; section.\n&quot;]
        instructions += [&quot;3. Click on &#39;Create New Expense Report&#39; or similar option.\n&quot;]
        instructions += [&quot;4. Fill in the required details such as expense items, amounts, dates, etc.\n&quot;]
        instructions += [&quot;5. Attach any relevant receipts or supporting documents.\n&quot;]
        instructions += [&quot;6. Review the expense report for accuracy.\n&quot;]
        instructions += [&quot;7. Submit the expense report for approval.\n\n&quot;]

        response = instructions

    else:
        response = [&quot;Sorry, I didn&#39;t understand your query. Can you please rephrase it?&quot;]

    output_box.insert(tk.END, &#39;Bot: &#39;)
    for line in response:
        if type(line) is list:
            output_box.insert(tk.END, *line)
        else:
            output_box.insert(tk.END, line)
    output_box.see(tk.END)  # Scrolls the output box to show the latest
    output_box.configure(state=&quot;disabled&quot;)

Then you need to bind the mouse click event on the tag to open the hyperlink using webbrowser.open():

output_box = scrolledtext.ScrolledText(root, width=80, height=10, font=(&quot;Arial&quot;, 12))
output_box.configure(state=&#39;disabled&#39;)  # Disable editing the output box
output_box.pack()

def open_link(event):
    # get the index of mouse click position
    current = output_box.index(f&quot;@{event.x},{event.y}&quot;)
    # find the hyperlink under the mouse click
    ranges = list(output_box.tag_ranges(&quot;url&quot;))
    for start, end in zip(ranges[::2], ranges[1::2]):
        if output_box.compare(start, &quot;&lt;=&quot;, current) and output_box.compare(current, &quot;&lt;&quot;, end):
            url = output_box.get(start, end)
            webbrowser.open(url)
            break

output_box.tag_bind(&quot;url&quot;, &quot;&lt;1&gt;&quot;, open_link)
output_box.tag_config(&quot;url&quot;, foreground=&quot;blue&quot;, underline=1)

huangapple
  • 本文由 发表于 2023年5月25日 01:34:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76326100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定