Question

I am trying to write a basic tkinter example that will show a box stretching across a frame. At this point the code below will only print the final result, and not show the box moving. How do I fix the code so that it will work over time with out using something like move, so that I can modify the shape over time later?

from tkinter import Tk, Canvas, Frame, BOTH
from time import sleep


class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   
        self.parent = parent 
        self.parent.title("Board")  
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self)         
        self.ctr = 10
        self.initUI()


    def initUI(self):
        print(self.ctr)
        #The first four parameters are the x,y coordinates of the two bounding points.
        #The top-left and the bottom-right. 
        r = self.canvas.create_rectangle((self.ctr * 10), 0, (self.ctr * 10 + 50), 50,
            outline="#fb0", fill="#fb0")
        '''
        canvas.create_rectangle(50, 0, 100, 50,
            outline="#f50", fill="#f50")
        canvas.create_rectangle(100, 0, 150, 50,
            outline="#05f", fill="#05f")
        '''         
        self.canvas.pack(fill=BOTH, expand=1)

        if self.ctr > 0:
            self.updateUI()

    def updateUI(self): 
            self.ctr -= 1
            sleep(1)
            self.initUI()



def main():

    root = Tk()
    root.geometry("400x100+300+300")
    ex = Example(root)
    root.mainloop()  


if __name__ == '__main__':
    main() 
Was it helpful?

Solution

This should get you partway there (you'll need to fix the indenting, the offsets are not correct and the counter doesn't get reset). In future, make sure you don't call sleep when you are using the event loop of a GUI for example. Most GUI's have a method to hook something into their event loops (the root.after call in this case). All I've done is make your code work partially - this should not be seen as indicative of idiomatic python.

from tkinter import Tk, Canvas, Frame, BOTH
from time import sleep

class Example(Frame):

def __init__(self, parent):
    Frame.__init__(self, parent)
    self.parent = parent
    self.parent.title("Board")
    self.pack(fill=BOTH, expand=1)
    self.canvas = Canvas(self)
    self.ctr = 10


def initUI(self):
    print(self.ctr)
    #The first four parameters are the x,y coordinates of the two bounding points.
    #The top-left and the bottom-right.
    r = self.canvas.create_rectangle((self.ctr * 10), 0, (self.ctr * 10 + 50), 50,
        outline="#fb0", fill="#fb0")
    '''
    canvas.create_rectangle(50, 0, 100, 50,
        outline="#f50", fill="#f50")
    canvas.create_rectangle(100, 0, 150, 50,
        outline="#05f", fill="#05f")
    '''
    self.canvas.pack(fill=BOTH, expand=1)

    self.ctr += 1
    if self.ctr > 0:
        self.parent.after(1000, self.initUI)

def main():

root = Tk()
ex = Example(root)
root.geometry("400x100+300+300")
root.after(1000, ex.initUI)
root.mainloop()

if __name__ == '__main__':
main()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top