英文:
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 fromfunctools 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:
Just click link and will to you to page.
Another screesnhot:
答案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, "go to ", "", "http://www.google.com", "url", ...)
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("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"]
# assign tag "url" to the hyperlink
instructions += [["1. Log in to Fusion Tool using your credentials ", "", "https://www.python.org", "url", "\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: ')
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="disabled")
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=("Arial", 12))
output_box.configure(state='disabled') # Disable editing the output box
output_box.pack()
def open_link(event):
# get the index of mouse click position
current = output_box.index(f"@{event.x},{event.y}")
# find the hyperlink under the mouse click
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论