nar*_*ero 6 python user-interface tkinter
关闭python 3程序时,我在控制台中遇到一个奇怪的异常.
Python 3代码:
from tkinter import *
from random import randint
# Return a random color string in the form of #RRGGBB
def getRandomColor():
color = "#"
for j in range(6):
color += toHexChar(randint(0, 15)) # Add a random digit
return color
# Convert an integer to a single hex digit in a character
def toHexChar(hexValue):
if 0 <= hexValue <= 9:
return chr(hexValue + ord('0'))
else: # 10 <= hexValue <= 15
return chr(hexValue - 10 + ord('A'))
# Define a Ball class
class Ball:
def __init__(self):
self.x = 0 # Starting center position
self.y = 0
self.dx = 2 # Move right by default
self.dy = 2 # Move down by default
self.radius = 3
self.color = getRandomColor()
class BounceBalls:
def __init__(self):
self.ballList = [] # Create a list for balls
window = Tk()
window.title("Bouncing Balls")
### Create Canvas ###
self.width = 350
self.height = 150
self.canvas = Canvas(window, bg = "white", width = self.width, height = self.height)
self.canvas.pack()
### Create Buttons ###
frame = Frame(window)
frame.pack()
btStop = Button(frame, text = "Stop", command = self.stop)
btStop.pack(side = LEFT)
btResume = Button(frame, text = "Resume", command = self.resume)
btResume.pack(side = LEFT)
btAdd = Button(frame, text = "Add", command = self.add)
btAdd.pack(side = LEFT)
btRemove = Button(frame, text = "Remove", command = self.remove)
btRemove.pack(side = LEFT)
self.sleepTime = 20
self.isStopped = False
self.animate()
window.mainloop()
def stop(self): # Stop animation
self.isStopped = True
def resume(self):
self.isStopped = False
self.animate()
def add(self): # Add a new ball
self.ballList.append(Ball())
def remove(self):
self.ballList.pop()
def animate(self):
while not self.isStopped:
self.canvas.after(self.sleepTime)
self.canvas.update()
self.canvas.delete("ball")
for ball in self.ballList:
self.redisplayBall(ball)
def redisplayBall(self, ball):
if ball.x > self.width or ball.x < 0:
ball.dx = -ball.dx
if ball.y > self.height or ball.y < 0:
ball.dy = -ball.dy
ball.x += ball.dx
ball.y += ball.dy
self.canvas.create_oval(ball.x - ball.radius, ball.y - ball.radius, \
ball.x + ball.radius, ball.y + ball.radius, \
fill = ball.color, tags = "ball")
BounceBalls()
Run Code Online (Sandbox Code Playgroud)
这是完整的Traceback:
/Library/Frameworks/Python.framework/Versions/3.3/bin/python3 "/Users/narek_a/Dropbox/Python/PycharmProjects/Introduction to Programming/Chapter 10.py"
Traceback (most recent call last):
File "/Users/narek_a/Dropbox/Python/PycharmProjects/Introduction to Programming/Chapter 10.py", line 446, in <module>
BounceBalls()
File "/Users/narek_a/Dropbox/Python/PycharmProjects/Introduction to Programming/Chapter 10.py", line 407, in __init__
self.animate()
File "/Users/narek_a/Dropbox/Python/PycharmProjects/Introduction to Programming/Chapter 10.py", line 428, in animate
self.canvas.delete("ball")
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 2344, in delete
self.tk.call((self._w, 'delete') + args)
_tkinter.TclError: invalid command name ".4302957584"
Process finished with exit code 1
Run Code Online (Sandbox Code Playgroud)
为什么会引起这些例外?
Bry*_*ley 10
当您退出程序时,窗口将被销毁。这种破坏发生在事件循环注意到应用程序已经退出之后。根据您构建代码的方式,这在您调用self.update(). 在该调用之后,并且在小部件被销毁之后,您立即调用self.canvas.delete("ball"). 由于小部件在上一条语句中被销毁,因此您会收到错误消息。
错误如此神秘的原因是 Tkinter 只是 tcl/tk 解释器的包装器。Tk 小部件以点号后跟一些字符命名,小部件名称也是 tcl 命令。当您调用delete画布的方法时,Tkinter 会将画布引用转换为内部 tk 小部件名称 / tcl 命令。由于小部件已被销毁,tk 无法将其识别为已知命令并引发错误。
该解决方案将要求您重做动画逻辑。你不应该有自己的动画循环。相反,您需要使用 Tkinter 事件mainloop()循环( ) 作为您的动画循环。本站点上有一些示例向您展示如何操作(例如:https : //stackoverflow.com/a/11505034/7432)
window.mainloop如果不按下stop按钮,主应用程序循环将永远不会执行。这是你问题的根源。重写动画循环:
def __init__(self):
...
self.sleepTime = 20
self.isStopped = False
self.window = window
self.window.after(self.sleepTime, self.animate)
window.mainloop()
...
def animate(self):
if not self.isStopped:
self.canvas.update()
self.canvas.delete("ball")
for ball in self.ballList:
self.redisplayBall(ball)
self.window.after(self.sleepTime, self.animate)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23683 次 |
| 最近记录: |