I think I saw something like this on the internet:
Tkinter uses double buffering to avoid flicker.
What does this mean and how and where?
3 Answers
It means that tkinter will save a bunch of UI changes in memory, and only update the display once for all pending changest. The update will happen when update
is called or mainloop
is re-entered.
-
Thank you Bryan your answer gave me a general explanation on the topic. Commented May 13, 2023 at 15:05
Graphical application typically have these components:
- a scene graph: this is the logical description of the application
- a back buffer: this is an array of pixels that actually gets modified by low level draw commands
- a front buffer: this is an array of pixels describing the image that are actually sent to the monitor
When you make a Tkinter draw commands, you're not actually directly changing the screen. Instead, you're just modifying the scene graph. In Tkinter, the objects in the scene graphs are the Tk/Python objects that you're calling.
When your application calls the function to update the screen (or when you reenter the main loop) the scene graph are flushed. This means that the scene graph are interpreted, and the UI library calls the low level draw routines that updates the image in the back buffer.
At the end of the flushing phase, the front and back buffer are flipped. This means that the buffer that used to be used as a back buffer now becomes the front buffer, and a new back buffer is allocated (or more commonly, the old front buffer now becomes the new back buffer).
Concurrently with all that, the monitor will always read what to draw on the screen from the front buffer.
All these updating and flipping means that the front buffer never contains partially updated image, even if the update rate of the application and the update rate of the screen doesn't match, the frames are always perfectly drawn.
Without double buffering, what could happen is that the application will draw images directly into the same buffer that the monitor reads pixel data from. In a single buffer system, you can sometimes see screen flickering or tearing, which is when part of the screen displays images that comes from previous frame and the other part of the screen displays images from the next frame.
None of this is specific to Tkinter, but pretty much all graphic systems would have something similar in their rendering pipeline, though they vary in exact details and terminologies may vary. In graphical systems that uses GPU, the buffers may actually be in GPU memory instead of the main memory; some graphic frameworks may not have any scene graphs as they expect the application to design any logical description of the scene themselves (and keep track of dirty pixels); sometimes the front buffer may have post processing applied before being sent to the screen so it doesn't directly correspond to the actual images on screen; sometimes the front buffer may actually be composited by a windowing system into a bigger scene; etc, etc.
While Bryan's answer is correct, I think this question deserves a little bit more depth.
-Be aware that the following is just my impression of some comments I've read in the past in the tcl/tk source code!
First you need to understand that graphical user interfaces are in fact graphics and for each graphic on your screen exists a structure, a graphical context. The graphical context describes the properties of each graphic and by updating these structures the operating system updates the graphic on your screen.
While you could fire each change directly to the operating system and update the graphics immediately the result would be that you see the changes on each graphic, rather than they are updated as a convoluted group, which results in flickering. That's why tcl/tk stores these context's/structures again for themselves and just shows the final result and not the entire redrawing process.
*It is also nice to know that this should apply for every widget, including canvases with their items.