tkinter redraw rates

Dave Angel davea at davea.name
Tue Jul 16 21:40:15 EDT 2013


On 07/16/2013 08:57 PM, fronagzen at gmail.com wrote:
> Hm. So I've written a GUI in tkinter. I've found two performance issues, I was hoping someone could point me in the right direction.
>
> Firstly, I'm using an image as a border, namely:

     <SNIP>
>
> This works, yes, but is annoyingly laggy on an older computer when I try to move the window around. I figure it's because the program has to keep redrawing the image border when dragged around, and is exacerbated by the fact that I have two of the imageborder frames in my application. How can I remedy this? I've tried using a hard-drawn image on a Canvas instead of the image border, but it's suboptimal because that prevents resizing the window.
>

This part I can't help with, as I'm not that familiar with tkinter in 
particular.  If I had to guess an approach, I'd tell you to create an 
object that represents the scaled border image, and then when it moves, 
you just reblit it.  And if/when the scale changes, you then recreate 
the object at the new scale.  Most of the time you won't be scaling.

But what that means in tkinter calls, I don't know and don't have time 
tonight to figure out.

>
> The other performance issue I've found is that when the logic is running, the app doesn't redraw. Ordinarily this would be acceptable, but as part of my program, it loads data from a website, and during the load, the window completely freezes up and doesn't respond until the download is done; as I understand it, tkinter doesn't redraw until it is forced to by .update() or control is given back to the mainloop. How can I force a more frequent redraw rate?
>

Tkinter, like every other GUI I know of, is event driven.  You're not 
intended to do "logic is running" kinds of events.  Break up larger 
problems into little tasks, and daisy chain them, returning to the event 
loop after each little piece.

A second approach that works with some GUI's is to fire up the event 
loop at periodic intervals in your long function;  get it to do a few 
other events and then return to you.  This isn't recommended usually 
because it can get very messy.  And it may not even be possible in tkinter.

Third approach is to start another thread to do the "logic is running." 
  Make sure that thread never calls any GUI stuff, but just updates 
values that can be seen by the main thread and its GUI stuff.  When 
you're done, post a message to the GUI to tell it to redraw whichever 
parts are now changed.


-- 
DaveA




More information about the Python-list mailing list