世界!在python中的turtle图形中,可以创建各种Turtle对象并使用它们的方法操作它们,向前,向后......我想尝试线程,所以我编写了一个名为MyTurtleManipulator的线程类。
from threading import Thread
from cTurtle import Turtle
import random
class MyTurtleManipulator(Thread):
def __init__(self, turtle):
Thread.__init__(self)
self.turtle=turtle
def run(self):
actions=[Turtle.forward, Turtle.right, Turtle.left]
while True:
action=random.choice(actions)
action(self.turtle, random.randint(1,25))
turtles=[Turtle() for i in range(5)]
threads=[MyTurtleManipulator(turtle) for turtle in turtles]
for thread in threads:
print(thread)
thread.start()
通过实验我希望看到所有的海龟“同时”和随机地移动但是当我运行程序时我得到了这些错误:
<MyTurtleManipulator(Thread-1, initial)>
<MyTurtleManipulator(Thread-2, initial)>
<MyTurtleManipulator(Thread-3, initial)>
<MyTurtleManipulator(Thread-4, initial)>
<MyTurtleManipulator(Thread-5, initial)>
>>> Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
self.run()
File "/home/rfrm/test.py", line 13, in run
action(self.turtle, random.randint(1,25))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1162, in forward
checkargs((int, float))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1131, in _go
ende = self._position + self._orient * distance
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2266, in _goto
(start, self._position),
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 419, in _drawline
cl.append(-y)
File "<string>", line 1, in coords
File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
self.run()
File "/home/rfrm/test.py", line 13, in run
action(self.turtle, random.randint(1,25))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1203, in right
checkargs((int, float))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2300, in _rotate
self._orient = self._orient.rotate(delta)
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2085, in _update
for t in screen._turtles:
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2219, in _drawturtle
screen._drawpoly(titem, shape, fill=fc, outline=oc,
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 384, in _drawpoly
cl.append(-y)
File "<string>", line 1, in coords
File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
self.run()
File "/home/rfrm/test.py", line 13, in run
action(self.turtle, random.randint(1,25))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1162, in forward
checkargs((int, float))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1131, in _go
ende = self._position + self._orient * distance
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2270, in _goto
screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 419, in _drawline
cl.append(-y)
File "<string>", line 1, in coords
File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop
Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
self.run()
File "/home/rfrm/test.py", line 13, in run
action(self.turtle, random.randint(1,25))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1162, in forward
checkargs((int, float))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1131, in _go
ende = self._position + self._orient * distance
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2270, in _goto
screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 419, in _drawline
cl.append(-y)
File "<string>", line 1, in coords
File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop
Exception in thread Thread-5:
Traceback (most recent call last):
File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
self.run()
File "/home/rfrm/test.py", line 13, in run
action(self.turtle, random.randint(1,25))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1203, in right
checkargs((int, float))
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2300, in _rotate
self._orient = self._orient.rotate(delta)
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2085, in _update
for t in screen._turtles:
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2219, in _drawturtle
screen._drawpoly(titem, shape, fill=fc, outline=oc,
File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 384, in _drawpoly
cl.append(-y)
File "<string>", line 1, in coords
File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop
这意味着什么,“主线程不在主循环中”是什么意思。谢谢你的帮助。
答案 0 :(得分:1)
这似乎是一个python / tkinter限制as described here,龟和线程不是朋友
答案 1 :(得分:0)
这有其局限性,但仍有可能。答案就在你的错误中:
RuntimeError:主线程不在主循环中
将turtle / tkinter操作限制为主线程。在我对下面的示例进行的修改中,我使用了线程安全的队列数据结构来在线程和乌龟之间进行通信:
from threading import Thread, active_count
from turtle import Turtle, Screen
import queue
import random
QUEUE_SIZE = 1 # set higher the more hardware threads you have
ACTIONS = [Turtle.forward, Turtle.right, Turtle.left]
COLORS = ['red', 'black', 'blue', 'green', 'magenta']
class MyTurtleManipulator(Thread):
def __init__(self, turtle):
super().__init__()
self.turtle = turtle
def run(self):
for _ in range(100):
actions.put((self.turtle, random.choice(ACTIONS), random.randint(1, 30)))
def process_queue():
while not actions.empty():
turtle, action, argument = actions.get()
action(turtle, argument)
if active_count() > 1:
screen.ontimer(process_queue, 100)
actions = queue.Queue(QUEUE_SIZE)
for color in COLORS:
turtle = Turtle('turtle')
turtle.color(color)
turtle.setheading(random.randint(0, 360))
MyTurtleManipulator(turtle).start()
screen = Screen()
process_queue()
screen.mainloop()
我在一台只有两个线程的机器上将QUEUE_SIZE设置为1!我很想知道在一个有更多线程的机器上是否一切正常并且QUEUE_SIZE~ = #threads - 1