我写了一个小测试程序,绘制了一些彩色线条。这是代码:
import sys
import math
import time
from tkinter import *
def testPlot(cv, w, h):
g = GraphParams(0, 0, w, 'blue')
pa = Palette(64)
pa.addCol(Color(0, 255, 255))
pa.addCol(Color(255, 255, 0))
pa.addCol(Color(255, 0, 255))
vq = 2/3 + .000001
xq = 1/3
t = 20000
for i in range(0, t):
vp = vq
xp = xq
vq = 4*vp*(1 - vp)
xq = 4*xp*(1 - xp)
g.col = pa.calcCol(i)
line(cv, g, xp, vp, xq, vq)
if i % 250 == 0:
cv.update()
class GraphParams:
def __init__(self, x0, y0, s0, c0):
self.x0 = x0
self.y0 = y0
self.scale = s0
self.col = c0
def line(cv, sc, xp, yp, xq, yq):
x0 = int((xp + sc.x0) * sc.scale)
y0 = int((yp + sc.y0) * sc.scale)
x1 = int((xq + sc.x0) * sc.scale)
y1 = int((yq + sc.y0) * sc.scale)
cv.create_line(x0, y0, x1, y1, fill=sc.col)
class Color:
def __init__(self, r, g, b):
self.red = r
self.gre = g
self.blu = b
def hexVal(self, v):
return (hex(v)[2:]).zfill(2)
def colStr(self):
return "#" + self.hexVal(self.red) + self.hexVal(self.gre) +
self.hexVal(self.blu)
class Palette:
def __init__(self, n0):
self.colors = []
self.n = n0
self.m = 0
def addCol(self, c):
self.colors.append(c)
self.m += 1
def calcCol(self, i):
k = i % (self.n*self.m)
z = k // self.n
j = k % self.n
c0 = self.colors[z]
c1 = self.colors[(z + 1) % self.m]
t0 = (self.n - j)/self.n
t1 = j/self.n
r = int(math.floor(c0.red*t0 + c1.red*t1))
g = int(math.floor(c0.gre*t0 + c1.gre*t1))
b = int(math.floor(c0.blu*t0 + c1.blu*t1))
c = Color(r, g, b)
return c.colStr()
class MenuFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.WIDTH = 800
self.HEIGHT = 800
self.canvas = Canvas(self.parent, width=self.WIDTH, height=self.HEIGHT)
self.pack(side=BOTTOM)
self.canvas.pack(side=TOP, fill=BOTH, expand=1)
self.parent.title("Simple menu")
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Menu(menubar)
fileMenu.add_command(label="Test Plot", command=self.onTestPlot)
fileMenu.add_command(label="Exit", command=self.onExit)
menubar.add_cascade(label="File", menu=fileMenu)
def onTestPlot(self):
testPlot(self.canvas, self.WIDTH, self.HEIGHT)
def onExit(self):
self.quit()
def main():
root = Tk()
frame = MenuFrame(root)
root.mainloop()
if __name__ == '__main__':
main()
如果我在完成绘图之前中止程序,我会得到以下异常:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1482, in __call__
return self.func(*args)
File "C:\Users\Daniel\Documents\Python\LineTest.py", line 92, in onTestPlot
testPlot(self.canvas, self.WIDTH, self.HEIGHT)
File "C:\Users\Daniel\Documents\Python\LineTest.py", line 23, in testPlot
line(cv, g, xp, vp, xq, vq)
File "C:\Users\Daniel\Documents\Python\LineTest.py", line 39, in line
cv.create_line(x0, y0, x1, y1, fill=sc.col)
File "C:\Python34\lib\tkinter\__init__.py", line 2294, in create_line
return self._create('line', args, kw)
File "C:\Python34\lib\tkinter\__init__.py", line 2282, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: invalid command name ".55506312"
除了等到程序停止绘图之外,是否有一种简单的方法可以防止此异常? 感谢。
答案 0 :(得分:1)
您尝试在画布上调用不再存在的create_line
。
我建议在for
循环中添加某种检查或try / catch,绘制所有这些行以查看是否单击了退出按钮。
在玩完你的代码之后,我决定最喜欢这种方法:
try:
line(cv, g, xp, vp, xq, vq)
except TclError:
break
答案 1 :(得分:1)
添加self.parent.protocol('WM_DELETE_WINDOW', self.onExit)
以覆盖默认行为,它应该正常退出。
class MenuFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.protocol('WM_DELETE_WINDOW', self.onExit)
self.initUI()