pythontkinterlambdafeedparser

How to add a link to text in tkinter text widget with feedparser?


I would like to build a simple rss reader. I use the following code:

import tkinter as tk
import feedparser
import sqlite3
import webbrowser
NewsFeed = feedparser.parse("https://www.wired.com/feed/rss")

i = 0

def callback(url):
    webbrowser.open_new(url)

def output():

   for i in range(40):
        entry = NewsFeed.entries[i]
        textInput.tag_config("a",  foreground="black")
        textInput.insert(tk.END,  entry.title + "\n\n", "a")
        textInput.insert(tk.END,  entry.summary + "\n\n", "b")
        textInput.bind("<1>", lambda e: callback(entry.link))

root = tk.Tk()
root.geometry("710x640")
root.configure(bg='white')
root.title("RSS Reader")

scroll = tk.Scrollbar(root)
scroll.grid(row=1, column=1, rowspan=50, sticky='ns')

padybutton=3
photo1=tk.PhotoImage(file="ico/button.gif")

textInput=tk.Text(root, width=50, height=37)
textInput.grid(row=0, column=0, rowspan=50, padx=10, pady=10)
textInput.configure(yscrollcommand=scroll.set, wrap=tk.WORD)
scroll.configure(command=textInput.yview)
#photo1=tk.PhotoImage(file="ico/button.gif")

btnRead=tk.Button(root, height=1, width=10, text="Check", command=output)
btnRead.config(image=photo1, text="Update", compound="center", width="120",height="20",borderwidth="0", font=('Verdana', 10), fg='#FFFFFF')
btnRead.grid(row=2, column=3, sticky=tk.N, padx=padybutton, pady=padybutton)

root.mainloop()

The bind only attachs the last link to all text. How can I iterate through the links and bind them to each headline - is this possible at all? I assume not, as it is one text in the end, right? Anyone any ideas?


Solution

  • You need to use tag_bind() instead of bind() because bind() is widget-wise:

    def output():
       for i in range(40):
            entry = NewsFeed.entries[i]
            textInput.tag_config("a",  foreground="black")
            # str(i) is used in tag_bind() and "a" can be used for showing the link in underline
            textInput.insert(tk.END,  entry.title + "\n\n", ("a", str(i))) 
            textInput.insert(tk.END,  entry.summary + "\n\n", "b")
            textInput.tag_bind(str(i), "<1>", lambda e, url=entry.link: callback(url))
    
    ...
    
    textInput.tag_configure("a", underline=True) # show link with underline