0

There are 10 sliders, and each slider value-change changes the image in the window. But I can't find a way to do this without calling root.mainloop() in the change() function. This although causes stack overflow eventually and i checked that by printing traceback length('memory' variable).

root = tk.Tk()

class SliderClass:
    def __init__(self,i,j):
        global no
        self.no = no
        self.w = Scale(root, label="PCA_feature "+str(self.no+1), 
            from_=10, to=-10, tickinterval=0.1, orient=HORIZONTAL, showvalue=0)
        self.w.grid(row=i,column=j)
        self.w.bind("<ButtonRelease-1>", self.change)
        self.w.set(np.clip(z[self.no],-10.0,10.0))
        no +=1

    def change(self, event):
        memory = ''.join(traceback.format_stack())
        print(len(memory))
        z[self.no] = self.w.get()
        z_inv = pca.inverse_transform(z).reshape((1,-1))
        im = G.layers[2].predict(z_inv)
        im = (0.5 * im + 0.5)*255
        im = im[0,:,:,:].astype('uint8')
        im = cv2.resize(im,(150,150))
        im = Image.fromarray(im)
        im = PhotoImage(im)
        panel.configure(image=im)
        root.mainloop()

im = Image.fromarray(im)
im = PhotoImage(im)
panel = Label(root, image = im, width=300,height=300)
panel.grid(rowspan=2,column=0)

r,c = 2,5
for i in range(r):
    for j in range(1,c+1):
        s = SliderClass(i,j)
        sliders.append(s)

root.mainloop()
Aravind
  • 83
  • 8
  • 1
    What happens if you just don't call mainloop() inside change? Typically you don't need to "manually hand off" control back to the mainloop. Merely returning will do that automatically. – Kevin Feb 05 '19 at 14:40
  • The image that I am supposed to change disappears. – Aravind Feb 05 '19 at 14:45
  • 1
    Read [Why does Tkinter image not show up if created in a function?](https://stackoverflow.com/a/16424553/7414759) and [Understanding the logic of Tkinter mainloop()](https://stackoverflow.com/a/26089368/7414759) – stovfl Feb 05 '19 at 14:50
  • Thank you so much :D The first link solved my problem. – Aravind Feb 05 '19 at 14:54

1 Answers1

0

You do not need to call mainloop in your function. It should be called exactly once for the life of your program.

The fact that the image doesn't show when you remove the call to mainloop is because you aren't storing a reference to the image so it gets deleted by the garbage collector when the function goes out of scope. By running mainloop in the function you prevent that from happening, but cause even worse problems (namely, the one you're writing about)

In addition to removing the call to mainloop inside your function, you need to save a reference to the image object. A simple change would be to use an attribute like self.im rather than the local variable im.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685