关闭Tkinter Python程序时出现异常

时间:2014-06-08 16:14:37

标签: python exception menu tkinter

我写了一个小测试程序,绘制了一些彩色线条。这是代码:

    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"

除了等到程序停止绘图之外,是否有一种简单的方法可以防止此异常? 感谢。

2 个答案:

答案 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()