0

I have a code for a "Magic Mirror" where I want to display clock, title and news (in Japanese).

I have a whole code that works fine with a news code inside it - In Tkinter loop - news code takes whole messages with json, hide everything except of title, put them to the list and shows loop through it to show messages one by one. It works well in terminal, but I have a struggles to put it into Tkinter window loop - It loops through it and shows only the last news subject - I would like them all, one every 10 seconds, or so... Is there a way to do it please? I will be happy for every answer, thanks.

Here is THE Code


import tkinter as tk
from tkinter import *

startupscreen = tk.Tk()
startupscreen.title('Magic Mirror: Python Mod')
welcometext = tk.Label(startupscreen, font = ('caviar dreams', 40), bg='black', fg='white')
startupscreen.configure(background='black')
startupscreen.overrideredirect(True)
welcometext.config(text='Mirror: Vuoristo Mod')
welcometext.pack(side=LEFT, padx= 120, pady=80)
# Gets the requested values of the height and widht.
windowWidth = startupscreen.winfo_reqwidth()
windowHeight = startupscreen.winfo_reqheight()
# Gets both half the screen width/height and window width/height
positionRight = int(startupscreen.winfo_screenwidth()/3 - windowWidth/2)
positionDown = int(startupscreen.winfo_screenheight()/2 - windowHeight/2)

# Positions the window in the center of the page.
startupscreen.geometry("+{}+{}".format(positionRight, positionDown))
startupscreen.update()

import time
from newsapi import NewsApiClient
import os
import feedparser
import json
from time import sleep

decrypt = list()
global iteration
global timecount
global repull
global sleep
iteration = 0
timecount = 0
repull = 0
sleep = 0


while True:


    def tick(time1=''):
        time2 = time.strftime("%H")
        if time2 != time1:
            time1 = time2
            clock_frame.config(text=time2)
        clock_frame.after(200, tick)

    def tickk(time3=''):
        time4 = time.strftime(":%M:%S")
        if time4 != time3:
            time3 = time4
            clock_frame2.config(text=time4)
        clock_frame2.after(200, tickk)


    #This function waits for a certain amount of 'tocks' and then initiates 'newsheader' -function
    def tock():
        global timecount
        global repull
        global sleep
        global decrypt
        newstitle.after(200, tock)
        if timecount < 20:
            timecount +=1
        else:
            timecount = 0
            newsheader()
        if repull < 200:
            repull +=1

        if sleep < 800:
            sleep+=1
        else:
            sleep = 0
            motiondetector()


    #This function iterates over the news headlines. Iteration is the news number, 'itemlist' brings out only the title.
    def newsheader():
        url = 'https://news.google.com/rss?hl=ja&gl=JP&ceid=JP:ja'
        d = feedparser.parse(url)
        news = list()

        for i, entry in enumerate(d.entries, 1):
            p = entry.published_parsed
            sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)

            tmp = {
                "title": entry.title,
            #"link": entry.link,
                "sortkey": sortkey
                }

            news.append(tmp)

        news = sorted(news, key=lambda x: x['sortkey'])

        myDict = {}
# HERE IS THE PROBLEM, I HAVE LIKE 30 news IN `frequency`, BUT IT SHOWS ONLY LAST ONE
        for d in news:
            c = d['title']
            myDict[c] = myDict.get(c,0)+1
            frequency = myDict.keys()
            frequency = list(frequency)
            for x in range(len(frequency)):
                 source.config(text=str(frequency[x]))
                 x += 1


    root = tk.Tk()
    root.title('Mirror')
    lab = Label(root, text=" 日本", font = ('', 40), bg='black', fg='white')
    lab.pack(anchor=SW, fill=X, padx=45)
    masterclock = tk.Label(root)
    masterclock.pack(anchor=NW, fill=X, padx=45)
    masterclock.configure(background='black')
    clock_frame = tk.Label(root, font = ('caviar dreams', 130), bg='black', fg='white')
    clock_frame.pack(in_=masterclock, side=LEFT)
    clock_frame2 = tk.Label(root, font = ('caviar dreams', 70), bg='black', fg='white')
    clock_frame2.pack(in_=masterclock, side=LEFT, anchor = N, ipady=15)
    newstitle = tk.Label(root, font = ('caviar dreams', 30), bg='black', fg='white')
    newstitle.pack(side=BOTTOM, anchor=W, fill=X)
    source = tk.Label(root, font = ('caviar dreams', 20), bg='black', fg='white')
    source.pack(side=BOTTOM, anchor=W, fill=X)

    newsheader()
    tick()
    tickk()
    tock()

    root.attributes("-fullscreen", True)
    root.configure(background='black')
    startupscreen.destroy()
    root.mainloop()


  • create new function which will get next element from list and put in Label. and it will run again with `after(10000, )` You will need some variable to remeber which text you get 10 second ago. – furas Apr 22 '19 at 05:30

2 Answers2

0

You need to use threading. And you can create a Repeating class or a Background class to perform your news reading every 10 seconds like this.

CodeTripper
  • 336
  • 3
  • 11
0

This code use function display_next_item to get next element from list frequency and put in Label. And it use after() to do it again after 1 second. You can set 10 seconds but for test I use smaller value.

For tests I also had to removed fullscreen and newsapi (which I don't have installed)

import tkinter as tk
from tkinter import *

startupscreen = tk.Tk()
startupscreen.title('Magic Mirror: Python Mod')
welcometext = tk.Label(startupscreen, font = ('caviar dreams', 40), bg='black', fg='white')
startupscreen.configure(background='black')
startupscreen.overrideredirect(True)
welcometext.config(text='Mirror: Vuoristo Mod')
welcometext.pack(side=LEFT, padx= 120, pady=80)
# Gets the requested values of the height and widht.
windowWidth = startupscreen.winfo_reqwidth()
windowHeight = startupscreen.winfo_reqheight()
# Gets both half the screen width/height and window width/height
positionRight = int(startupscreen.winfo_screenwidth()/3 - windowWidth/2)
positionDown = int(startupscreen.winfo_screenheight()/2 - windowHeight/2)

# Positions the window in the center of the page.
startupscreen.geometry("+{}+{}".format(positionRight, positionDown))
startupscreen.update()

import time
#from newsapi import NewsApiClient
import os
import feedparser
import json
from time import sleep

decrypt = list()
global iteration
global timecount
global repull
global sleep
iteration = 0
timecount = 0
repull = 0
sleep = 0


while True:


    def tick(time1=''):
        time2 = time.strftime("%H")
        if time2 != time1:
            time1 = time2
            clock_frame.config(text=time2)
        clock_frame.after(200, tick)

    def tickk(time3=''):
        time4 = time.strftime(":%M:%S")
        if time4 != time3:
            time3 = time4
            clock_frame2.config(text=time4)
        clock_frame2.after(200, tickk)


    #This function waits for a certain amount of 'tocks' and then initiates 'newsheader' -function
    def tock():
        global timecount
        global repull
        global sleep
        global decrypt
        newstitle.after(200, tock)
        if timecount < 20:
            timecount +=1
        else:
            timecount = 0
            newsheader()
        if repull < 200:
            repull +=1

        if sleep < 800:
            sleep+=1
        else:
            sleep = 0
            motiondetector()


    #This function iterates over the news headlines. Iteration is the news number, 'itemlist' brings out only the title.
    def newsheader():
        url = 'https://news.google.com/rss?hl=ja&gl=JP&ceid=JP:ja'
        d = feedparser.parse(url)
        news = list()

        for i, entry in enumerate(d.entries, 1):
            p = entry.published_parsed
            sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)

            tmp = {
                "title": entry.title,
            #"link": entry.link,
                "sortkey": sortkey
                }

            news.append(tmp)

        news = sorted(news, key=lambda x: x['sortkey'])

        myDict = {}

        for d in news:
            c = d['title']
            myDict[c] = myDict.get(c,0)+1

        global frequency
        frequency = list(myDict.keys())


    def display_next_item():
        global frequency
        global next_index

        next_index += 1
        if next_index >= len(frequency):
            next_index = 0

        source.config(text=str(frequency[next_index]))

        root.after(1000, display_next_item)


    frequency = [] # value at start
    next_index = 0 # value at start

    root = tk.Tk()
    root.title('Mirror')
    lab = Label(root, text=" 日本", font = ('', 40), bg='black', fg='white')
    lab.pack(anchor=SW, fill=X, padx=45)
    masterclock = tk.Label(root)
    masterclock.pack(anchor=NW, fill=X, padx=45)
    masterclock.configure(background='black')
    clock_frame = tk.Label(root, font = ('caviar dreams', 130), bg='black', fg='white')
    clock_frame.pack(in_=masterclock, side=LEFT)
    clock_frame2 = tk.Label(root, font = ('caviar dreams', 70), bg='black', fg='white')
    clock_frame2.pack(in_=masterclock, side=LEFT, anchor = N, ipady=15)
    newstitle = tk.Label(root, font = ('caviar dreams', 30), bg='black', fg='white')
    newstitle.pack(side=BOTTOM, anchor=W, fill=X)
    source = tk.Label(root, font = ('caviar dreams', 20), bg='black', fg='white')
    source.pack(side=BOTTOM, anchor=W, fill=X)

    newsheader()
    tick()
    tickk()
    tock()
    display_next_item() # <- start displaying


    #root.attributes("-fullscreen", True)
    root.configure(background='black')
    startupscreen.destroy()
    root.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148
  • wow, thanks! It is not fullscreen, but it can be easily done, right? –  Apr 22 '19 at 05:48
  • I have made it to full screen, but the headlines (japanese) is too long and didnt fit to screen, is there a way to make it fit to screen- make two lines or so? –  Apr 22 '19 at 06:56
  • It should be method to get text size and then you can try to split it and test if it will fit - but I never had to use it so I don't remeber it. There is also widget [Text()](http://effbot.org/tkinterbook/text.htm) which has option `wrap=` so it should display long text in many lines. But I'm not sure if it works correctly on every system – furas Apr 22 '19 at 07:19
  • Thanks! Gonna check it –  Apr 22 '19 at 07:21