0

I am new to python and I have a little problem with tkinter.
And yes, I know how to use google but I havent found solutions for it. Maybe coz I don't really know how and what to look for, maybe coz of my bad english :P.

I have 3 functions

  • tick() #refresh the time each 200ms if the time is not the old time
  • refreshT() # refresh temperatures (read from 3 file)
  • refreshW() #refresh a weather widget (an image)

They call themselves after 200ms, each 5s and every 30m.

The problem is, that the time dont update for ~2 seconds if refreshT is called.

I've read something about threads here but I didnt understand it. So, my question is how can i give a specific function a higher priority or do anything else that it keeps running whatever happens?

I dont expect finish code just some infos about some modules or so which do what Im looking for.

Im using raspbian on a raspi 3b if it is relevant.

Here is the interesting part of the code:

#Python 3.5.3:

#(...)
def tick():
    try:                           #tests if there is an old time to compare
        timeOld                    #if not, set it to none
    except NameError:
        timeOld = None
    timeNew = getTime(1)           #a module ive written, returning the time 
                                   #in a specific order
    if timeOld != timeNew:         #compare (this is to avoid running the
                                   #function to often, better for performance
        clock.config(text=timeNew) #display the new time
        timeOld = timeNew          #set the old time to the actual time
    clock.after(200, tick)         #call itself after 200ms

def refreshT():                        #refreshing temperatures
    tempCpu.config(text=(round(float(open('/sys/class/thermal/thermal_zone0/temp').read())/1000, 1),'°C'))
    tempIns.config(text=(round(float(open('/sys/bus/w1/devices/28-0417a312a0ff/w1_slave').read().split('t=')[1])/1000, 1),'°C'))
    tempOut.config(text=(round(float(open('/sys/bus/w1/devices/28-0517a27018ff/w1_slave').read().split('t=')[1])/1000, 1),'°C'))
    tempCpu.after(5000, refreshT)  #call itself after 5 sec

def refreshW(refresh=True):
    if refresh == True:
        weather_raw = createImg(Ids[1])
        weather.config(image=weather_raw) #reload image
        weather.image = weather_raw
    weather.after(1800000, refreshW) #call itself after 30min
#(...)
root = Tk()
#(...)
clock = Label(
    root,
    font=('Helvetica', 50),
    text=texts[0],
    fg='white',
    bg='black',
    cursor='none'
)
clock.place(
    relx=0.5,
    y=242,
    anchor='n'
)

tempCpu = Label(
    root,
    font=('Helvetica', 40),
    text='$CPU°C',
    fg='white',
    bg='black',
    cursor='none'
)
tempCpu.place(
    relx=0.2,
    y=100,
    anchor='n'
)
tempIns = Label(
    root,
    font=('Helvetica', 40),
    text='$INS°C',
    fg='white',
    bg='black',
    cursor='none'
)
tempIns.place(
    relx=0.5,
    y=100,
    anchor='n'
)
tempOut = Label(
    root,
    font=('Helvetica', 40),
    text='$OUT°C',
    fg='white',
    bg='black',
    cursor='none'
)
tempOut.place(
    relx=0.8,
    y=100,
    anchor='n'
)

tick()
refreshT()
refreshW(False)
root.mainloop()

If this code will not work, here is the full code on Github.

Hope for help or a link to an answer, sorry if this is a duplicate.

Billal Begueradj
  • 20,717
  • 43
  • 112
  • 130
  • 1
    There seem to be quite a few problems, so which is the problem you are currently having? E.g., `timeOld` is a local variable, so there never is an existing `timeOld`. Also, the weather-image is probably being garbage-collected. Which of the three widgets is causing problems, and in what way exactly? – tobias_k May 26 '18 at 15:24
  • 1
    Also, I'd strongly recommend going to [codereview](https://codereview.stackexchange.com) with that code, too, as there's a _lot_ that can be improved, e.g. adding some empty lines and comments, helper functions for common label formatting and placement, avoiding `if x: return True else return False`, mixed return types in `getTime`, etc. – tobias_k May 26 '18 at 15:32
  • 1
    About what seems to be the problem: Probably reading the temperatures takes about 2 seconds, blocking the tkinter thread that long. You _could_ use threading for this, but IMHO that's somewhat overkill. Do you really have to show time in seconds, and if so, do you have to update time in seconds in 1/5 second intervals? Alternatively, you could call the `tick` function in between the three temperature readouts. – tobias_k May 26 '18 at 15:42
  • `weather` is undefined. – ivan_pozdeev May 26 '18 at 21:06
  • Neither is `texts` and `getTime`. Voting to close since no [mcve]. It's your job to throw away all code irrelevant to the problem you're asking about. – ivan_pozdeev May 26 '18 at 21:17
  • After removing all that/replacing with fakes, WFM. So the problem is not in tkinter's logic. If a background operation takes long, you need to [use a worker thread](https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing) to avoid freezing other logic. – ivan_pozdeev May 26 '18 at 21:39
  • thanks for your help. yes weather is undefined, i forgot to add. if the weather and the temperature is refreshing at a time it takes more longer. ivan: if i have troubles again i will short the code more in a future question. So I will try tobias_k's solution (calling the tick function in the other ones) If it doesnt work how i want to i will try to do something with threads... –  May 27 '18 at 01:51

0 Answers0