Python Tkinter is puzzling
I am new to Python trying to fill a canvas with random pixels. Can anyone tell me why it is doing horizontal stripes?
import tkinter
from random import randint
from binascii import hexlify
class App:
def __init__(self, t):
x=200
y=200
xy=x*y
b=b'#000000 '
s=bytearray(b*xy)
c = tkinter.Canvas(t, width=x, height=y);
self.i = tkinter.PhotoImage(width=x,height=y)
for k in range (0,8*xy,8):
s[k+1:k+7]=hexlify(bytes([randint(0,255) for i in range(3)]))
print (s[:100])
pixels=s.decode("ascii")
self.i.put(pixels,(0,0,x,y))
print (len(s),xy*8)
c.create_image(0, 0, image = self.i, anchor=tkinter.NW)
c.pack()
t = tkinter.Tk()
a = App(t)
t.mainloop()
Which gives, for example:
source to share
I would suggest you do something simpler like:
class App:
def __init__(self, t, w=200, h=200):
self.image = tkinter.PhotoImage(width=w, height=h) # create empty image
for x in range(w): # iterate over width
for y in range(h): # and height
rgb = [randint(0, 255) for _ in range(3)] # generate one pixel
self.image.put("#{:02x}{:02x}{:02x}".format(*rgb), (y, x)) # add pixel
c = tkinter.Canvas(t, width=w, height=h);
c.create_image(0, 0, image=self.image, anchor=tkinter.NW)
c.pack()
This is much easier to understand and gives me:
which I suspect is what you hoped for.
To reduce the number of image.put
s, note that the data format (for a 2x2 black image) is:
'{#000000 #000000} {#000000 #000000}'
Therefore you can use:
self.image = tkinter.PhotoImage(width=w, height=h)
lines = []
for _ in range(h):
line = []
for _ in range(w):
rgb = [randint(0, 255) for _ in range(3)]
line.append("#{:02x}{:02x}{:02x}".format(*rgb))
lines.append('{{{}}}'.format(' '.join(line)))
self.image.put(' '.join(lines))
which has only one image.put
(see for example Why does Photoimage fit slower? ) and gives a similar image. Your image was striped because it interpreted every pixel color as a line color, since you didn't include '{'
and '}'
for every line.
source to share