I am making a GUI in python using Tkinter and have had some performance issues when packing many widgets onto the screen, for example packing a 50x50 grid of buttons takes a few seconds.
It seems to be the process of drawing (or arranging?) the widgets onto the screen which takes the time. I have tried using both the grid and place geometry managers.
I am wondering if using multiprocessing might speed this up? I would welcome any other suggestions for any way in which this could be significantly sped up.
import Tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
for i in range(50):
for j in range(50):
widget = tk.Frame(frame, bd=2, relief='raised', height=10, width=10)
widget.grid(row=i, column=j) # using place is barely quicker
tk.Button(root, text='pack', command=frame.pack).pack()
root.mainloop()
As suggested in the comments, the best solution did end up being to use a canvas and draw onto it, rather than to pack so many widgets, which seems to have absolute limitations on its speed.
I used the built-in buttons by effectively taking a screenshot to create images of the unclicked and clicked states. Suppose the image files are stored as im_up.png
and im_down.png
, then the code below illustrates the canvas solution.
import Tkinter as tk
# Uses Python Imaging Library.
from PIL import Image as ImagePIL, ImageTk
root = tk.Tk()
canvas = tk.Canvas(root, height=500, width=500, highlightthickness=0)
canvas.pack()
images = dict()
for name in ['up', 'down']:
im = ImagePIL.open('im_{}.png'.format(name))
# Resize the image to 10 pixels square.
im = im.resize((10, 10), ImagePIL.ANTIALIAS)
images[name] = ImageTk.PhotoImage(im, name=name)
def set_cell_image(coord, image):
# Get position of centre of cell.
x, y = ((p + 0.5) * 10 for p in coord)
canvas.create_image(x, y, image=image)
for i in range(50):
for j in range(50):
set_cell_image((i, j), images['up'])
def click(event):
coord = tuple(getattr(event, p)/10 for p in ['x', 'y'])
set_cell_image(coord, images['down'])
canvas.bind('<Button-1>', click)
root.mainloop()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With