简体   繁体   中英

How to fix 'main thread is not in main loop' error in turtle, python library?

I'm trying to emulate a digitizer tablet with my notebook trackpad using the libraries Pynput and Turtle, but I keep geeting this same error:

RuntimeError: main thread is not in main loop

Here's the full code:

from pynput import mouse
import turtle as tt
import time

tt.speed(0)

class MyException(Exception): pass

def on_move(x,y):
    print('Pointer: {0}'.format((x,y)))
    pos = (x,y)
    tt.setpos(pos)

def on_click(x, y, button, pressed):
    if button == mouse.Button.left:
        raise MyException(button)

with mouse.Listener(
        on_click=on_click,
        on_move=on_move) as listener:
    try:
        listener.join()
    except MyException as e:
        print('{0} was clicked'.format(e.args[0]))
from pynput.mouse import Listener

def on_move(x, y):
    print('Pointer moved to {0}'.format(
        (x, y)))

def on_click(x, y, button, pressed):
    print('{0} at {1}'.format(
        'Pressed' if pressed else 'Released',
        (x, y)))
    if not pressed:
        # Stop listener
        return False

def on_scroll(x, y, dx, dy):
    print('Scrolled {0}'.format(
        (x, y)))

# Collect events until released
with Listener(
        on_move=on_move,
        on_click=on_click,
        on_scroll=on_scroll) as listener:
    listener.join()

from https://pythonhosted.org/pynput/mouse.html

I'm guessing that you're only importing pynput because the turtle screen object lacks the 'Motion' event of its tkinter underpinning. If so, we can instead install the missing event into turtle to implement your digitizer:

from turtle import Turtle, Screen, Vec2D
from functools import partial

class MyException(Exception):
    pass

def onscreenmove(self, fun, add=None):

    ''' Event method missing from turtle '''

    if fun is None:
        self.cv.unbind('<Motion>')
    else:
        def eventfun(event):
            fun(self.cv.canvasx(event.x) / self.xscale, -self.cv.canvasy(event.y) / self.yscale)

        self.cv.bind('<Motion>', eventfun, add)

def on_left_click(x, y):
    raise MyException(Vec2D(x, y))

def on_move(x, y):
    screen.onmove(None)  # disable events inside handler

    print('Pointer: {0}'.format(Vec2D(x, y)))

    turtle.setheading(turtle.towards(x, y))
    turtle.goto(x, y)

    screen.onmove(on_move)  # reenable handler

turtle = Turtle()
turtle.speed('fastest')

screen = Screen()
screen.onmove = partial(onscreenmove, screen)  # install missing method

screen.onmove(on_move)
screen.onclick(on_left_click, btn=1)  # btn=1 is the default

screen.mainloop()

SCREEN

在此处输入图片说明

CONSOLE

> python3 test.py
Pointer: (336.00,-73.00)
Pointer: (289.00,-56.00)
Pointer: (256.00,-43.00)
Pointer: (233.00,-35.00)
Pointer: (220.00,-31.00)
Pointer: (216.00,-30.00)
...
Pointer: (139.00,-37.00)
Pointer: (131.00,-35.00)
Pointer: (117.00,-25.00)
Pointer: (165.00,-24.00)
Pointer: (275.00,-28.00)
Pointer: (337.00,-29.00)
Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/turtle.py", line 675, in eventfun
    fun(x, y)
  File "test.py", line 20, in on_left_click
    raise MyException(Vec2D(x, y))
MyException: (151.00,334.00)
Pointer: (150.00,334.00)
Pointer: (147.00,334.00)
Pointer: (143.00,334.00)
...
Pointer: (20.00,273.00)
Pointer: (-46.00,306.00)
Pointer: (-141.00,360.00)
>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM