【问题标题】:How to fix 'main thread is not in main loop' error in turtle, python library?如何修复turtle,python库中的“主线程不在主循环”错误?
【发布时间】:2019-08-07 20:18:31
【问题描述】:

我正在尝试使用 Pynput 和 Turtle 库在我的笔记本触控板上模拟数字化平板电脑,但我一直收到同样的错误:

RuntimeError: 主线程不在主循环中

这是完整的代码:

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]))

【问题讨论】:

    标签: python emulation turtle-graphics pynput


    【解决方案1】:
    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()
    

    来自https://pythonhosted.org/pynput/mouse.html

    【讨论】:

    • Pynput 部分(获取触控板输入并使用监听器)我没问题。当我尝试与 Turtle 集成时,问题就来了。
    • 你必须为此使用多线程。一线程听二动乌龟
    • 是的,明白了。但我在实施时遇到了一些麻烦。有什么想法吗?
    【解决方案2】:

    我猜您只是导入 pynput,因为海龟屏幕对象缺少其 tkinter 基础的 'Motion' 事件。如果是这样,我们可以将缺失的事件安装到 turtle 中来实现您的数字化器:

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

    屏幕

    控制台

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2019-10-12
      • 2019-03-21
      相关资源
      最近更新 更多