Tkinter and hyperlinks

2019-09-04 04:03发布

问题:

I am writing a GUI in Tkinter and all it needs to do is have a search box, and then output the results as a hyperlink. I am having lots of trouble. What is the best way to do this?

I was able to open up a lot of webpages once the search terms are found. But I want to be able to display the hyperlinks and for the user to choose which to open. Any help is appreciated. Thanks!

This is my code so far:

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()

回答1:

Here's one way to do. It puts each href on a separate line in the text widget and tags the line with a unique tag name, each of which are bound to a separate, dynamically created, callback()event handler function which indirectly calls the real event handler. It's purpose is to supply it some extra arguments not normally passed by Tkinter. These "shim" event handlers make it possible to provide some visual feedback on which link was selected by temporarily turning its background to red before opening the web browser with it as the target url.

This default-keyword-argument-value trick is a commonly used technique to pass extra data to Tkinter event handlers. In this case it's being used to pass the neededhrefandtag_namearguments to it.

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()