Tkinter 和超链接

Tkinter and hyperlinks

我正在用 Tkinter 编写一个 GUI,它需要做的就是有一个搜索框,然后将结果作为超链接输出。我有很多麻烦。执行此操作的最佳方法是什么?

找到搜索词后,我能够打开很多网页。但我希望能够显示超链接并让用户选择打开哪个。任何帮助表示赞赏。谢谢!

到目前为止,这是我的代码:

from Tkinter import *
import json 
import webbrowser

with open('data.json', 'r') as f:
   database = json.loads(f.read())

def goto(event,href):
   webbrowser.open_new(href)

def evaluate(event):
   res.delete(1.0, END)
   search_param = str(entry.get())
   for patient_id in database:
      if search_param in str(database[patient_id]).lower():
         href = "https://website.com/" + str(patient_id)
         res.insert(INSERT, href, "link")
         res.bind("<Button-1>", goto(event, href))

w = Tk()
Label(w, text="Search:").pack()
entry = Entry(w)
entry.bind("<Return>", evaluate)
entry.pack()
res = Text(w)
res.pack()
w.mainloop()

这是一种方法。它将每个 href 放在文本小部件中的单独一行上,并用唯一的标签名称标记该行,每个标签名称都绑定到一个单独的、动态创建的 callback() 事件处理函数,该函数间接调用真正的事件处理程序。它的目的是为它提供一些 Tkinter 通常不传递的额外参数。这些 "shim" 事件处理程序可以提供一些关于 link 被选中的视觉反馈,方法是在将其作为目标 url 打开 Web 浏览器之前暂时将其背景变为红色。

这种默认关键字参数值技巧是将额外数据传递给 Tkinter 事件处理程序的常用技术。在这种情况下,它被用来向它传递所需的hreftag_name参数。

from Tkinter import *
import json
import time
import webbrowser

with open('data.json', 'r') as f:
    database = json.loads(f.read())

def goto(event, href, tag_name):
    res = event.widget
    res.tag_config(tag_name, background='red')  # change tag text style
    res.update_idletasks()  # make sure change is visible
    time.sleep(.5)  # optional delay to show changed text
    print 'opening:', href      # comment out
    #webbrowser.open_new(href)  # uncomment out
    res.tag_config(tag_name, background='white')  # restore tag text style
    res.update_idletasks()

def evaluate(event):
    res.delete('1.0', END)
    search_param = str(entry.get())
    link_count = 0
    for patient_id in database:
        if search_param in str(database[patient_id]).lower():
            href = "https://website.com/" + str(patient_id)
            tag_name = "link" + str(link_count)  # create unique name for tag
            link_count += 1
            # shim to call real event handler with extra args
            callback = (lambda event, href=href, tag_name=tag_name:
                            goto(event, href, tag_name))
            res.tag_bind(tag_name, "<Button-1>", callback) # just pass function
                                                           # (don't call it)
            res.insert(INSERT, href+'\n', (tag_name,))  # insert tagged text

w = Tk()
Label(w, text="Search:").pack()
entry = Entry(w)
entry.bind("<Return>", evaluate)
entry.pack()
res = Text(w)
res.pack()
w.mainloop()