tkinter redraw rates
davea at davea.name
Wed Jul 17 03:40:15 CEST 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:
> 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.
More information about the Python-list