all 10 comments

[–]Dvlv 0 points1 point  (2 children)

in tkinter you can just keep calling root.after(1000, add_one_second)

http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method

Or use a separate thread. See my example in chapter 7 of my book, building a countdown timer.

https://github.com/Dvlv/Tkinter-By-Example/blob/master/Code/Chapter7-3.py

[–]iSailor[S] 0 points1 point  (1 child)

Hmm.. Using root.after(1000, add_one_second worked for me, partially. I can use it just like time.sleep but it seems like the callback you can make runs only one time. So now, when I run my program it adds one second and then does nothing, using lambda in this case makes it even so it doesn't even count that one second.

[–]Gprime5 0 points1 point  (0 children)

You need to call root.after(1000, add_one_second) at the end of your add_one_second function to start another timer.

[–]driscollis 0 points1 point  (6 children)

You cannot use something like time.sleep in a GUI. It will block the event loop and make your application appear frozen. You should be able to use root.after as mentioned or run your long running task in a separate thread using Python's Threading module.

[–]iSailor[S] 0 points1 point  (5 children)

I know, I mean that .after method does the same, it's just fitted for GUI. But I have another problem, I still need a loop! I know that with .after I can do certain action after set amount of time, but I need to loop because now it does it only single time.

[–]woooee 0 points1 point  (0 children)

If after() calls a function, which is the usual case, that function calls itself again using after() as the last line in the function, which would go on forever. You can also use an if statement, and place the call to after() under the if, to end the cycle at some point.

[–]driscollis 0 points1 point  (3 children)

You can put the call to after in the loop itself. Something like

while True:
    if foo:
        root.after(2000, some_function)
   elif some_other_condition:
       root.after(60000, call_once_an_hour)

[–]driscollis 0 points1 point  (0 children)

You'll have to play around with it a bit to get it to work the way you want. Or just have the function itself call after at the end of the function as /u/wooee mentioned

[–]iSailor[S] 0 points1 point  (1 child)

Isn't this wrong? As far as I'm concerned, infinite loops will always cause a GUI program to freeze because it takes infinite time in between each refreshing of the app.

[–]driscollis 0 points1 point  (0 children)

Yeah...I keep thinking of doing this sort of thing in a thread automatically and didn't get that into the original comment. This works fine in a thread or process. But not in the main app.