Tkinter RSS Тикер ускоряется при каждом обновлении - PullRequest
0 голосов
/ 08 января 2019

Нет никакой помощи в Google, я также спросил некоторых людей, но никто из них, кажется, не знает, как ответить на мой вопрос.

Я программирую графический интерфейс для проекта, и он содержит тикер RSS-ленты. Он прокручивает новости и, когда он обновляется (каждые 3 секунды по очевидным причинам отладки), немного ускоряется. Это означает, что если я запустил программу, то через два часа тикер прокручивается со скоростью, не читаемой человеком.

Основной код был написан не мной, я изменил его и добавил функцию обновления.

main():

import tkinter as tk
from Press import RSSTicker

def displayRSSticker(win):
    # Place RSSTicker portlet
    tickerHandle = RSSTicker(win, bg='black', fg='white', highlightthickness=0, font=("avenir", 30))
    tickerHandle.pack(side='bottom', fill='x', anchor='se')

def main():
    # Set the screen definition, root window initialization
    root = tk.Tk()
    root.configure(background='black')
    width, height = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry("%dx%d+0+0" % (width, height))
    label = tk.Label(root, text="Monitor Dashboard", bg='black', fg='red')
    label.pack(side='bottom', fill='x', anchor='se')

    # Display portlet
    displayRSSticker(root)
    # Loop the GUI manager
    root.mainloop(0)

###############################
#     MAIN SCRIPT BODY PART   #
###############################
if __name__ == "__main__":
    main()

Класс RSSTicker:

import feedparser
import tkinter as tk

class RSSTicker(tk.Text):
    # Class constructor
    def __init__(self, parent, **params):
        super().__init__(parent, height=1, wrap="none", state='disabled', **params)
        self.newsFeed = feedparser.parse('http://www.repubblica.it/rss/homepage/rss2.0.xml')
        self.update()

    # Class methods
    def update(self):
        self.headlineIndex = 0
        self.text = ''
        self.pos = 0
        self.after_idle(self.updateHeadline)
        self.after_idle(self.scroll)
        self.after(4000, self.update)

    def updateHeadline(self):
        try:
            self.text += '       ' + self.newsFeed['entries'][self.headlineIndex]['title']
        except IndexError:
            self.headlineIndex = 0
            self.text = self.feed['entries'][self.headlineIndex]['title']

        self.headlineIndex += 1
        self.after(5000, self.updateHeadline)

    def scroll(self):
        self.config(state='normal')
        if self.pos < len(self.text):
            self.insert('end', self.text[self.pos])
        self.pos += 1
        self.see('end')
        self.config(state='disabled')
        self.after(180, self.scroll)

Я думал, что проблема заключается в переменной self.pos, ее распечатка привела к ее подсчету, сбросу к 1 и более быстрому отсчету. Но, похоже, это не проблема, вызывающая ускорение тикера. Из того, что я понял, проблема должна быть в методе прокрутки.

Если кто-то понимает, как сохранить оригинальную скорость прокрутки при обновлении, спасибо.

1 Ответ

0 голосов
/ 08 января 2019

Я думаю, вы можете использовать пару переменных отслеживания, чтобы убедиться, что update запускает цикл только один раз, а затем при следующем вызове update он просто запустит scroll без запуска нового цикла. В то же время, если scroll не вызван update, он продолжит цикл по мере необходимости.

Измените свой RSSTicker класс на следующий:

class RSSTicker(tk.Text):
    # Class constructor
    def __init__(self, parent, **params):
        self.scroll_started = False # Tracker for first update.
        super().__init__(parent, height=1, wrap="none", state='disabled', **params)
        self.newsFeed = feedparser.parse('http://www.repubblica.it/rss/homepage/rss2.0.xml')
        self.update()

    def update(self):
        self.headlineIndex = 0
        self.text = ''
        self.pos = 0
        self.after_idle(self.updateHeadline)
        self.after_idle(lambda: self.scroll('update'))
        self.after(4000, self.update)

    def updateHeadline(self):
        try:
            self.text += '       ' + self.newsFeed['entries'][self.headlineIndex]['title']
        except IndexError:
            self.headlineIndex = 0
            self.text = self.feed['entries'][self.headlineIndex]['title']

        self.headlineIndex += 1
        self.after(5000, self.updateHeadline)

    def scroll(self, from_after_or_update = 'after'):
        self.config(state='normal')
        if self.pos < len(self.text):
            self.insert('end', self.text[self.pos])
        self.pos += 1
        self.see('end')
        self.config(state='disabled')
        # Check if the loop started by after.
        if from_after_or_update != 'update':
            self.scroll_started = True
            self.after(180, self.scroll)
        # If not started by after check to see if it is the 1st time loop is started by "update".
        elif self.scroll_started is False and from_after_or_update == 'update':
            self.scroll_started = True
            self.after(180, self.scroll)
        # If neither of the above conditions then do not start loop to prevent multiple loops.
        else:
            print("ran scroll method without adding new after loop!")
...