尝试运行两个线程时出错

时间:2017-01-18 00:12:48

标签: python multithreading turtle-graphics

我有两种不同的方法,一种用箭头键控制乌龟,另一种控制一组自动乌龟。当我运行程序时,我收到此错误

Unhandled exception in thread started by <function falconMove at 0x7f6c9af61aa0>
Traceback (most recent call last):
  File "/home/bernardk/Code/Python/FinalProject/FinalProject.py", line 198, in falconMove
    wn.onkey(up, "Up")
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 1343, in onkey
    self._onkey(fun, key)
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 711, in _onkey
    self.cv.bind("<KeyRelease-%s>" % key, eventfun)
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 440, in bind
    self._canvas.bind(*args, **kwargs)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1098, in bind
    return self._bind(('bind', self._w), sequence, func, add)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1048, in _bind
    needcleanup)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1220, in _register
    self.tk.createcommand(name, f)
RuntimeError: main thread is not in main loop
Unhandled exception in thread started by <function evilMove at 0x7f6c9af61b18>
Traceback (most recent call last):
  File "/home/bernardk/Code/Python/FinalProject/FinalProject.py", line 211, in evilMove
    traveler.forward(travelerSpeed)
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 1553, in forward
    self._go(distance)
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 1521, in _go
    self._goto(ende)
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 2991, in _goto
    screen._pointlist(self.currentLineItem),
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 761, in _pointlist
    cl = self.cv.coords(item)
  File "<string>", line 1, in coords
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2300, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

这是线程使用的代码。

def falconMove(a):
    time.sleep(.1)
    global wn
    wn.onkey(up, "Up")
    wn.onkey(left, "Left")
    wn.onkey(right, "Right")
    wn.onkey(down, "Down")
    wn.listen()

def evilMove(a):
    time.sleep(.1)
    global alive
    global success
    global blockNum
    global traveler
    global travelerSpeed
    traveler.forward(travelerSpeed)

    for i in range(0, len(evil), 1):
        evil[i].forward(speed[i] + (travelerSpeed * 2))
        for j in range(0, len(evil), 1):
            if collide(turt, evil[j]):
                alive = False
                success = False
            if collide(traveler, evil[j]):
                alive = False
                success = False
        if evil[i].ycor() < -(height / 2):
            evilReset(i, False)
        if collide(turt, nice):
            blockNum += 1
            nice.goto(random.randint(-(width / 2) + 20, (width / 2) - 20),
                      random.randint(-(height / 2) + 120, (height / 2) - 20))
            buildBlock(blockNum, True)
        if blockNum == 9 or traveler.xcor() > width / 2:
            success = True
            alive = False


thread.start_new_thread(falconMove, (1,))
thread.start_new_thread(evilMove, (1,))

如果需要,这是整个计划

import turtle
import random
import gtk
import threading
import thread
import time

travelerSpeed = 0
while travelerSpeed > 10 or travelerSpeed < 1:
    travelerSpeed = input("Enter the difficulty(1-10): ")

#Turtle Settings
wn = turtle.Screen()
falcon = "/home/bernardk/Code/Python/FinalProject/ship.gif"
falconR = "/home/bernardk/Code/Python/FinalProject/shipR.gif"
falconL = "/home/bernardk/Code/Python/FinalProject/shipL.gif"
falconD = "/home/bernardk/Code/Python/FinalProject/shipD.gif"
wn.addshape(falcon)
turt = turtle.Turtle()
turtle.bgcolor("black")
turt.pu()
turt.shape(falcon)
turt.fillcolor("snow")
turt.goto(0, 0)

#Screen Setup
window = gtk.Window()
screen = window.get_screen()
width = screen.get_width()
height = screen.get_height()
wn.screensize()
wn.setup(width=1.0, height=1.0)

#Key Action Handelers
def up():
    global falcon
    turt.setheading(90)
    #turt.shape(falcon)
    turt.forward(2)

def left():
    global falconL
    turt.setheading(180)
    #turt.shape(falconL)
    turt.forward(2)

def right():
    global falconR
    turt.setheading(0)
    #turt.shape(falconR)
    turt.forward(2)

def down():
    global falconD
    turt.setheading(270)
    #turt.shape(falconD)
    turt.forward(2)

#Supports on the Bottom
builder = turtle.Turtle()
builder.tracer(0)
builder.pencolor("snow")
builder.fillcolor("snow")
builder.ht()
startx = -width/2
starty = (-height/2) + 100
blockWidth = width/10
blockHeight = 50

def buildBlock(num, fill):
    builder.pu()
    builder.goto(startx + (blockWidth*num), starty)
    builder.pd()
    if fill:
        builder.begin_fill()
    builder.setheading(0)
    for i in range(2):
        builder.forward(blockWidth)
        builder.right(90)
        builder.forward(blockHeight)
        builder.right(90)

    if fill:
        builder.end_fill()

for i in range(10):
    buildBlock(i, False)

#Make the helpless traveler
traveler = turtle.Turtle()
traveler.pu()
traveler.pensize(2)
traveler.goto(-width/2, (-height/2) + 25)
traveler.setheading(0)
traveler.pencolor("navy")
traveler.pd()
traveler.pensize(3)

#Laser Colors
colors = ["blue2", "green2", "red", "purple3", "snow", "yellow2"]

#Declare Nice Guy
nice = turtle.Turtle()
nice.shape("circle")
nice.fillcolor("cyan")
nice.pencolor("cyan")
nice.pu()
nice.goto(random.randint((-width / 2) + 20, (width / 2) - 20), random.randint((-height/2) + 120, (height / 2) - 20))

#Declare Evil Entities
e0 = turtle.Turtle()
e1 = turtle.Turtle()
e2 = turtle.Turtle()
e3 = turtle.Turtle()
e4 = turtle.Turtle()
e5 = turtle.Turtle()
e6 = turtle.Turtle()
e7 = turtle.Turtle()
e8 = turtle.Turtle()
e9 = turtle.Turtle()
e10 = turtle.Turtle()
e12 = turtle.Turtle()
e13 = turtle.Turtle()
e14 = turtle.Turtle()
e15 = turtle.Turtle()
e16 = turtle.Turtle()
e17 = turtle.Turtle()
e18 = turtle.Turtle()
e19 = turtle.Turtle()
e20 = turtle.Turtle()
e21 = turtle.Turtle()
e22 = turtle.Turtle()
e23 = turtle.Turtle()
e24 = turtle.Turtle()
e25 = turtle.Turtle()
e26 = turtle.Turtle()
e27 = turtle.Turtle()
e28 = turtle.Turtle()
e29 = turtle.Turtle()
e30 = turtle.Turtle()
e31 = turtle.Turtle()
e32 = turtle.Turtle()
e33 = turtle.Turtle()
e34 = turtle.Turtle()
e35 = turtle.Turtle()
e36 = turtle.Turtle()
e37 = turtle.Turtle()
e38 = turtle.Turtle()
e39 = turtle.Turtle()
e40 = turtle.Turtle()
e41 = turtle.Turtle()
e42 = turtle.Turtle()
e43 = turtle.Turtle()
e44 = turtle.Turtle()
e45 = turtle.Turtle()
e46 = turtle.Turtle()
e47 = turtle.Turtle()
e48 = turtle.Turtle()
e49 = turtle.Turtle()

evil = [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49,]
speed = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
difficulty = [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]

def evilReset(i, first):
    if difficulty[i] < 10:
        difficulty[i] += 1
    evil[i].tracer(0)
    if first:
        evil[i].goto(random.randint(-(width / 2), (width / 2)), random.randint((height / 2), (height * 1.5)))
    else:
        evil[i].goto(random.randint(-(width / 2), (width / 2)), random.randint((height / 2), (height/2 + 30)))
    evil[i].tracer(1)
    speed[i] = random.randint(5, difficulty[i])
    evil[i].fillcolor(colors[random.randint(0, 5)])
    evil[i].setheading(270)

for i in range(0, len(evil), 1):
    evil[i].pu()
    evilReset(i, True)

def collide(turt1, turt2):
    if turt1.xcor() - turt2.xcor() < 10:
        if turt.ycor() - nice.ycor() < 10:
            return True
        else:
            return False
    else:
        return False

alive = True
success = False
blockNum = -1

def falconMove(a):
    time.sleep(.1)
    global wn
    wn.onkey(up, "Up")
    wn.onkey(left, "Left")
    wn.onkey(right, "Right")
    wn.onkey(down, "Down")
    wn.listen()

def evilMove(a):
    time.sleep(.1)
    global alive
    global success
    global blockNum
    global traveler
    global travelerSpeed
    traveler.forward(travelerSpeed)

    for i in range(0, len(evil), 1):
        evil[i].forward(speed[i] + (travelerSpeed * 2))
        for j in range(0, len(evil), 1):
            if collide(turt, evil[j]):
                alive = False
                success = False
            if collide(traveler, evil[j]):
                alive = False
                success = False
        if evil[i].ycor() < -(height / 2):
            evilReset(i, False)
        if collide(turt, nice):
            blockNum += 1
            nice.goto(random.randint(-(width / 2) + 20, (width / 2) - 20),
                      random.randint(-(height / 2) + 120, (height / 2) - 20))
            buildBlock(blockNum, True)
        if blockNum == 9 or traveler.xcor() > width / 2:
            success = True
            alive = False


thread.start_new_thread(falconMove, (1,))
thread.start_new_thread(evilMove, (1,))


#for thread in thread_list:
#    thread.start()
#    thread.join()

while alive:
    #Turtle Movement
    pass


if success:
    exit()
    print("Congrats you Won")
else:
    exit()
    print("You suck better luck next time")

print("The End")

#turtle.mainloop()

我知道代码很乱,而且它不是一个有效的程序,我只是想先让线程工作。谢谢:))

1 个答案:

答案 0 :(得分:2)

我不相信你需要一个线程来做你想做的事 - 你可以简单地使用turtle ontimer()事件。我已经按照这些方式重新编写了代码来证明这一点:

from turtle import Turtle, Screen
import random

travelerSpeed = 0
while travelerSpeed > 10 or travelerSpeed < 1:
    travelerSpeed = int(input("Enter the difficulty(1-10): "))

# Screen Setup
screen = Screen()
screen.bgcolor("black")
screen.setup(width=1.0, height=1.0)
width = screen.window_width()
height = screen.window_height()

# Turtle Settings
# falcon = "/home/bernardk/Code/Python/FinalProject/ship.gif"
# screen.addshape(falcon)

turt = Turtle(shape="turtle")
turt.speed("fastest")
turt.fillcolor("snow")
turt.pu()
turt.goto(0, 0)

# Key Action Handlers
def up():
    turt.setheading(90)
    turt.forward(2)

def left():
    turt.setheading(180)
    turt.forward(2)

def right():
    turt.setheading(0)
    turt.forward(2)

def down():
    turt.setheading(270)
    turt.forward(2)

# Supports on the Bottom
builder = Turtle(visible=False)
builder.color("snow")

startx = -width / 2
starty = (-height / 2) + 100
blockWidth = width / 10
blockHeight = 50

def buildBlock(num, fill):
    builder.pu()
    builder.goto(startx + (blockWidth * num), starty)
    builder.pd()

    if fill:
        builder.begin_fill()

    builder.setheading(0)
    for _ in range(2):
        builder.forward(blockWidth)
        builder.right(90)
        builder.forward(blockHeight)
        builder.right(90)

    if fill:
        builder.end_fill()

screen.tracer(0)
for i in range(10):
    buildBlock(i, False)
screen.tracer(1)

# Make the helpless traveler
traveler = Turtle()
traveler.pensize(3)
traveler.pencolor("navy")
traveler.setheading(0)
traveler.pu()
traveler.goto(-width / 2, -height / 2 + 25)
traveler.pd()

# Laser Colors
colors = ["blue", "green", "red", "purple", "white", "yellow"]

# Declare Nice Guy
nice = Turtle(shape="circle")
nice.pencolor("cyan")
nice.pu()
nice.goto(random.randint((-width / 2) + 20, (width / 2) - 20), random.randint((-height / 2) + 120, (height / 2) - 20))

# Declare Evil Entities
evil = [Turtle() for _ in range(50)]
speed = [0] * len(evil)
difficulty = [6] * len(evil)

def evilReset(i, first):
    if difficulty[i] < 10:
        difficulty[i] += 1
    if first:
        evil[i].goto(random.randint(-width // 2, width // 2), random.randint(-height // 2, height // 2))
    else:
        evil[i].goto(random.randint(-width // 2, width // 2), random.randint(-height // 2 + 30, height // 2))
    speed[i] = random.randint(5, difficulty[i])
    evil[i].fillcolor(random.choice(colors))
    evil[i].setheading(270)

screen.tracer(0)
for i, entity in enumerate(evil):
    entity.pu()
    evilReset(i, True)
screen.tracer(1)

def collide(turt1, turt2):
    if turt1.xcor() - turt2.xcor() < 10:
        return turt1.ycor() - turt2.ycor() < 10

    return False

alive = True
success = False
blockNum = -1

def evilMove():
    global alive
    global success
    global blockNum

    traveler.forward(travelerSpeed)

    for i in range(len(evil)):
        evil[i].forward(speed[i] + (travelerSpeed * 2))
        for j in range(len(evil)):
            if collide(turt, evil[j]):
                alive = False
                success = False
            if collide(traveler, evil[j]):
                alive = False
                success = False
        if evil[i].ycor() < -(height / 2):
            evilReset(i, False)
        if collide(turt, nice):
            blockNum += 1
            nice.goto(random.randint(-(width / 2) + 20, (width / 2) - 20), random.randint(-(height / 2) + 120, (height / 2) - 20))
            buildBlock(blockNum, True)
        if blockNum == 9 or traveler.xcor() > width / 2:
            success = True
            alive = False

    if not alive:
        if success:
            print("Congrats you Won")
        else:
            print("You suck, better luck next time")

        print("The End")
        exit()

    screen.ontimer(evilMove, 100)

screen.onkey(up, "Up")
screen.onkey(left, "Left")
screen.onkey(right, "Right")
screen.onkey(down, "Down")
screen.listen()

screen.ontimer(evilMove, 100)

screen.mainloop()

它并不完美,但应该让你了解可能的事情。