2014-06-08 2 views
0

나는 색깔있는 선을 그려주는 작은 테스트 프로그램을 작성했습니다. 여기 코드는 다음과 같습니다Tkinter Python 프로그램을 닫을 때 예외

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" 

이 예외를 방지하는 쉬운 방법은 때까지 기다리는 것보다 다른 거기를 프로그램이 그리기를 중단합니까? 감사합니다. .

+1

어떻게 프로그램을 중지 하시겠습니까? –

+0

양식을 닫음. – tyebillion

+1

어디에서 실행하고 있습니까? –

답변

1

캔버스에 더 이상 존재하지 않는 create_line을 호출하려고합니다. exit 버튼을 클릭했는지 확인하기 위해 루프를 모두 그려주는 for 루프에 어떤 종류의 체크 또는 try/catch를 추가하는 것이 좋습니다.

try: 
    line(cv, g, xp, vp, xq, vq) 
except TclError: 
    break 
+0

try 블록에 "if i % 250 == 0 :"및 "cv.update()"를 넣습니다. – tyebillion

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() 
+0

IDLE에서 실행 중입니다. "프로토콜"라인을 추가했지만 지금은 아무 것도 발생하지 않고 창을 닫으려면 클릭하면 프로그램이 계속 그려집니다. – tyebillion

+0

명령 줄 –

+0

에서 스크립트로 실행하면 어떻게됩니까? 예를 들면 그림 그리기가 끝난 후에 만 ​​양식을 닫습니다. 지연된 반응. – tyebillion