【问题标题】:Is it possible to display hyperlinks in a Tkinter message widget?是否可以在 Tkinter 消息小部件中显示超链接?
【发布时间】:2016-11-28 13:45:11
【问题描述】:

我正在创建一个新闻提要程序,它使用 Feedparser 模块来读取 Yahoo! RSS API,将关键数据写入文本文件,然后在 Tkinter GUI 中组织显示数据。

我在询问是否可以在文本文件/Tkinter 消息小部件中包含可点击的超链接。

我目前的想法是您可以编写以以下方式运行的代码:

  • 如果文本文件中的项目包含“http”,则将其设为超链接。

如果有人知道实现这一点的 Pythonic 方法,或者知道这实际上是否可行,请贡献。

感谢您的宝贵时间,这是我的代码:

def news_feed(event):
    ''' This function creates a new window within the main window, passes an event(left mouse click), and creates a text heading'''

    root = Toplevel(window)

    # Create a text heading and define its placement within the grid
    menu_heading = Label(root, text = 'News feed', font = 'bold')
    menu_heading.grid(row = 0, column = 0, columnspan = 3, pady = 4)

    # Create a variable of the selected radio button
    button_choice = IntVar()

    def selection():
        ''' This function gets the activated radio button and calls its corresponding function.'''

        # Get the value of the activated radio button, and call its corresponding function
        news_choice = button_choice.get()

        # If the user's choice is industry news, ask them which feed they would like (E.g. Stock market),
        if news_choice == 0:
            # grab the corresponding url segment to the user's feed choice from the dictionary,
            news_choice_url = news_areas[news_feed]
            # set the url variable using by inserting this segment into the API url,
            rss_url = feedparser.parse('https://au.finance.yahoo.com/news/' + news_choice_url + '/?format=rss')
            # and call the feed parsing function.
            parse_feed()
        # If the user's choice is the second button, call the company news function
        elif news_choice == 1:
            company_news()

    def read_news_file(news_feed_message):
        '''This function opens the companyNews text file and reads its contents, line by line'''
        with open('C:\\Users\\nicks_000\\PycharmProjects\\untitled\\SAT\\GUI\\Text Files\\companyNews.txt', mode='r') as inFile:
            news_data_read = inFile.read()
            print('\n')
        news_feed_message.configure(text = news_data_read)

    def parse_feed(news_feed_message, rss_url):
        ''' This function parses the Yahoo! RSS API for data of the latest five articles, and writes it to the company news text file'''

        # Define the RSS feed to parse from, as the url passed in of the company the user chose
        feed = feedparser.parse(rss_url)

        try:
            # Define the file to write the news data to the company news text file
            with open('C:\\Users\\nicks_000\\PycharmProjects\\untitled\\SAT\\GUI\\Text Files\\companyNews.txt', mode='w') as outFile:

                # Create a list to store the news data parsed from the Yahoo! RSS
                news_data_write = []
                # Initialise a count
                count = 0
                # For the number of articles to append to the file, append the article's title, link, and published date to the news_elements list
                for count in range(10):
                    news_data_write.append(feed['entries'][count].title)
                    news_data_write.append(feed['entries'][count].published)
                    article_link = (feed['entries'][count].link)
                    article_link = article_link.split('*')[1]
                    news_data_write.append(article_link)
                    # Add one to the count, so that the next article is parsed
                    count+=1
                    # For each item in the news_elements list, convert it to a string and write it to the company news text file
                    for item in news_data_write:
                        item = str(item)
                        outFile.write(item+'\n')
                    # For each article, write a new line to the company news text file, so that each article's data is on its own line
                    outFile.write('\n')
                    # Clear the news_elements list so that data is not written to the file more than once
                    del(news_data_write[:])
        finally:
            outFile.close()

        read_news_file(news_feed_message)

    def industry_news():
        ''' This function creates a new window within the main window, and displays industry news'''

        industry_window = Toplevel(root)
        Label(industry_window, text = 'Industry news').grid()

    def company_news():
        ''' This function creates a new window within the main window, and displays company news'''

        company_window = Toplevel(root)
        company_label = Label(company_window, text = 'Company news')
        company_label.grid(row = 0, column = 0, columnspan = 6)

        def company_news_handling(company_ticker):
            ''' This function gets the input from the entry widget (stock ticker) to be graphed.'''

            # set the url variable by inserting the stock ticker into the API url,
            rss_url = ('http://finance.yahoo.com/rss/headline?s={0}'.format(company_ticker))
            # and call the feed parsing function.
            parse_feed(news_feed_message, rss_url)

        # Create the entry widget where the user enters a stock ticker, and define its location within the grid
        company_ticker_entry = Entry(company_window)
        company_ticker_entry.grid(row = 1, column = 0, columnspan = 6, padx = 10)

        def entry_handling():
            '''This function validates the input of the entry box, and if there is nothing entered, an error is outputted until a value is'''

            # Create a variable that equals the input from the entry widget
            company_ticker = company_ticker_entry.get()

            # Convert the input into a string
            company_ticker = str(company_ticker)

            if company_ticker == '':
                news_feed_message.configure(text = 'Please input a stock ticker in the entry box.')
            else:
                company_news_handling(company_ticker)

        # Create the button that the user presses when they wish to graph the data of the stock ticker they inputted in the entry widget
        graph_button = Button(company_window, text = 'SHOW', command = entry_handling, width = 10).grid(row = 2, column = 0, columnspan = 6)

        news_feed_message = Message(company_window, text='', width=500, borderwidth=5, justify=LEFT, relief=RAISED)
        news_feed_message.grid(row=3, column=0, columnspan=6)

【问题讨论】:

    标签: python hyperlink tkinter rss feedparser


    【解决方案1】:

    我见过的 tkinter 应用程序中超链接的大多数使用涉及使用 webbrowser 并将事件附加到您的 tkinter 对象以触发回调,但可能有更简单的方法,但这就是我的意思:

    from tkinter import *
    import webbrowser
    
    def callback(event):
        webbrowser.open_new(r"http://www.google.com")
    
    root = Tk()
    link = Label(root, text="Google Hyperlink", fg="blue", cursor="hand2")
    link.pack()
    link.bind("<Button-1>", callback)
    root.mainloop()
    

    来自source

    你可以按照你说的做,从文本文件中读取,如果该行包含“http”,则创建一个新标签和事件,将文件的超链接附加到事件。

    import re
    
    with open(fname) as f:
        content = f.readlines()
        urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', content)
    

    在此之后访问 url 并生成您的标签或您附加 url 的任何小部件,然后您可以让所有这些小部件在单击时打开网页。

    希望这对您有所帮助,如果您需要更多帮助,请告诉我 :)

    【讨论】:

      【解决方案2】:

      我认为使用以下链接在 tkinter 中创建超链接很容易,并且很容易根据您的要求进行修改

      Updated Hyperlink in tkinter

      希望这对你有用。

      问候米顿

      【讨论】:

      • “tkinter 中的超链接”将我带到一个与 tkinter 中的超链接无关的页面。
      【解决方案3】:

      (来自 effbot 的答案) 文本超链接支持模块(文件:tkHyperlinkManager.py)

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

      这是一个例子:

      # File: hyperlink-1.py
      
      import tkHyperlinkManager
      
      from Tkinter import *
      
      root = Tk()
      root.title("hyperlink-1")
      
      text = Text(root)
      text.pack()
      
      hyperlink = tkHyperlinkManager.HyperlinkManager(text)
      
      def click1():
          print "click 1"
      
      text.insert(INSERT, "this is a ")
      text.insert(INSERT, "link", hyperlink.add(click1))
      text.insert(INSERT, "\n\n")
      
      def click2():
          print "click 2"
      
      text.insert(INSERT, "this is another ")
      text.insert(INSERT, "link", hyperlink.add(click2))
      text.insert(INSERT, "\n\n")
      
      mainloop()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-04
        • 2013-03-06
        • 1970-01-01
        相关资源
        最近更新 更多