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()
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.