mardi 6 mai 2014

python - changer l'interface graphique au fil du temps en Tkinter - Stack Overflow


I am building a conway's game of life graphics using Tkinter in {ython. The game logic and everything else is fine, I just stuck on the last one part of code which I can't figure out even after reading the library.


self.after(1000,self.draw(bigThing))

Here is the full code:


from Tkinter import *
from button import *
import numpy
import test1
import time

class AppFrame(Frame):


def __init__(self,root, buttonlist):
Frame.__init__(self, root, relief='sunken', width=600, height=600)
self.gameisrunning = False
self.buttonlist = buttonlist
self.root = root

self.w = Canvas(self,width = 505, height =505)


self.boulis = []
for k in range(1,101):
for i in range(1, 101):

button = Buttons(self.w, i * 5, k * 5, i * 5 + 5, k * 5 + 5,k ,i,buttonlist)
self.boulis.append(button)


self.whole = list(self.chunks(self.boulis, 100))

self.grid(column =0, columnspan = 4)
self.w.grid(column = 0)

clear = Button(self.root,text = "clear")
clear.grid(column = 0, row = 1)
self.run = Button(self.root,text = "run", command = self.runit)
self.run.grid(column = 3, row = 1)
self.root.mainloop()

def runit(self):

if self.gameisrunning == False:
self.gameisrunning = True
self.transformer = self.buttonlist
while self.gameisrunning == True:
bigThing = test1.theNextBigThing(self.transformer)
self.transformer = bigThing
self.root.after(1000,self.draw, bigThing)


elif self.gameisrunning == True:
self.gameisrunning = False


def draw (self, board):
for k in range (0, 100):
for i in range (0, 100):
if board[k + 1][i + 1] == 1:
self.whole[k][i].activate()
elif board[k + 1][i + 1] == 0:
self.whole[k][i].deactivate()

def chunks(self,l, n):
""" Yield successive n-sized chunks from l.
"""
for i in xrange(0, len(l), n):
yield l[i:i+n]

I changed the structure a bit. It seems like anything I want to draw under the 'runit' method doesn't work. I don't know why it happens. All the other functions in 'runit' work perfectly fine. Only this didn't work:


self.root.after(1000,self.draw(bigThing))

Here is my button class:


##button.py
from Tkinter import *


class Buttons:

def __init__(self,canvas,bx,by,tx,ty, k, i,buttonlist):
self.buttonlist = buttonlist
self.canvas = canvas
self.rec = canvas.create_rectangle((bx,by,tx,ty),fill = "lightgray",
activefill= 'black', outline = 'lightgray')
self.canvas.tag_bind(self.rec, "<Button-1>", lambda event: self.callback())
self.active = False

self.k = k
self.i = i

self.xmin = bx
self.xmax = tx
self.ymin = by
self.ymax = ty
##print (bx, by, tx, ty)

def activate(self):
self.canvas.itemconfigure(self.rec, fill = 'black')

def deactivate(self):
self.canvas.itemconfig(self.rec, fill='lightgray')

def callback(self):
self.activate()
self.buttonlist[self.k][self.i] = 1



You're getting that error since your AppFrame.__init__ doesn't call the Frame superconstructor -- the AppFrame object is not a proper Tk object as a result. The code in that method seems to be combined with code that should be calling it and the Frame declared in it (self.f) should actually be self:


class AppFrame(Frame):
def __init__(self, root, buttonlist):
Frame.__init__(self, root, relief='sunken', width=600, height=600)
self.root = root
self.gameisrunning = False
self.w = Canvas(self.f, width = 505, height =505)

# [as before, but with self instead of self.f]

It's generally more modular to build your root object outside of an application-specific frame (this lets you embed your app in something other than the root):


def main():
root = Tk()
root.geometry = "1000x1000"
buttonlist = ... # needs to be filled in
app = AppFrame(root, buttonlist)

# ...


I am building a conway's game of life graphics using Tkinter in {ython. The game logic and everything else is fine, I just stuck on the last one part of code which I can't figure out even after reading the library.


self.after(1000,self.draw(bigThing))

Here is the full code:


from Tkinter import *
from button import *
import numpy
import test1
import time

class AppFrame(Frame):


def __init__(self,root, buttonlist):
Frame.__init__(self, root, relief='sunken', width=600, height=600)
self.gameisrunning = False
self.buttonlist = buttonlist
self.root = root

self.w = Canvas(self,width = 505, height =505)


self.boulis = []
for k in range(1,101):
for i in range(1, 101):

button = Buttons(self.w, i * 5, k * 5, i * 5 + 5, k * 5 + 5,k ,i,buttonlist)
self.boulis.append(button)


self.whole = list(self.chunks(self.boulis, 100))

self.grid(column =0, columnspan = 4)
self.w.grid(column = 0)

clear = Button(self.root,text = "clear")
clear.grid(column = 0, row = 1)
self.run = Button(self.root,text = "run", command = self.runit)
self.run.grid(column = 3, row = 1)
self.root.mainloop()

def runit(self):

if self.gameisrunning == False:
self.gameisrunning = True
self.transformer = self.buttonlist
while self.gameisrunning == True:
bigThing = test1.theNextBigThing(self.transformer)
self.transformer = bigThing
self.root.after(1000,self.draw, bigThing)


elif self.gameisrunning == True:
self.gameisrunning = False


def draw (self, board):
for k in range (0, 100):
for i in range (0, 100):
if board[k + 1][i + 1] == 1:
self.whole[k][i].activate()
elif board[k + 1][i + 1] == 0:
self.whole[k][i].deactivate()

def chunks(self,l, n):
""" Yield successive n-sized chunks from l.
"""
for i in xrange(0, len(l), n):
yield l[i:i+n]

I changed the structure a bit. It seems like anything I want to draw under the 'runit' method doesn't work. I don't know why it happens. All the other functions in 'runit' work perfectly fine. Only this didn't work:


self.root.after(1000,self.draw(bigThing))

Here is my button class:


##button.py
from Tkinter import *


class Buttons:

def __init__(self,canvas,bx,by,tx,ty, k, i,buttonlist):
self.buttonlist = buttonlist
self.canvas = canvas
self.rec = canvas.create_rectangle((bx,by,tx,ty),fill = "lightgray",
activefill= 'black', outline = 'lightgray')
self.canvas.tag_bind(self.rec, "<Button-1>", lambda event: self.callback())
self.active = False

self.k = k
self.i = i

self.xmin = bx
self.xmax = tx
self.ymin = by
self.ymax = ty
##print (bx, by, tx, ty)

def activate(self):
self.canvas.itemconfigure(self.rec, fill = 'black')

def deactivate(self):
self.canvas.itemconfig(self.rec, fill='lightgray')

def callback(self):
self.activate()
self.buttonlist[self.k][self.i] = 1


You're getting that error since your AppFrame.__init__ doesn't call the Frame superconstructor -- the AppFrame object is not a proper Tk object as a result. The code in that method seems to be combined with code that should be calling it and the Frame declared in it (self.f) should actually be self:


class AppFrame(Frame):
def __init__(self, root, buttonlist):
Frame.__init__(self, root, relief='sunken', width=600, height=600)
self.root = root
self.gameisrunning = False
self.w = Canvas(self.f, width = 505, height =505)

# [as before, but with self instead of self.f]

It's generally more modular to build your root object outside of an application-specific frame (this lets you embed your app in something other than the root):


def main():
root = Tk()
root.geometry = "1000x1000"
buttonlist = ... # needs to be filled in
app = AppFrame(root, buttonlist)

# ...

0 commentaires:

Enregistrer un commentaire