Why doesn't this monkey patch work for python turtle?

穿精又带淫゛_ 提交于 2021-02-11 15:31:16

问题


So I'm trying to monkey patch the onkey function in turtle so it calls a function with the button hit instead of just calling it with no arguments. I'm using the string "tester" to see if it works, but it looks like the original functions never got changes. Can someone explain what I'm doing wrong?

from threading import Thread
from time import sleep
from turtle import *

def NEWonkeypress(self, fun, key=None):
    if fun is None:
        if key in self._keys:
            self._keys.remove(key)
    elif key is not None and key not in self._keys:
        self._keys.append(key)
    self._onkeypress(fun, key)

def _NEWonkeypress(self, fun, key=None):
    if fun is None:
        if key is None:
            self.cv.unbind("<KeyPress>", None)
        else:
            self.cv.unbind("<KeyPress-%s>" % key, None)
    else:
        def eventfun(event):
            fun("tester")
        if key is None:
            self.cv.bind("<KeyPress>", eventfun)
        else:
            self.cv.bind("<KeyPress-%s>" % key, eventfun)

Turtle.onkeypress = NEWonkeypress
Turtle._onkeypress = _NEWonkeypress

board = Turtle()
screen = board.getscreen()
screen.tracer(0, 0)
temp = Turtle()

def textinput(testing):
    print(testing)

def getroomname(option): 
    global temp
    global board
    #Box
    temp.fillcolor("White")
    temp.width(10)
    temp.goto(-150, -60)
    temp.down()
    temp.begin_fill()
    for x in range(2):
        temp.forward(300)
        temp.left(90)
        temp.forward(120)
        temp.left(90)
    temp.end_fill()
    temp.up()
    temp.goto(0, 100)
    screen.update()
    #Box
    temp.goto(0, -60)
    screen.onkeypress(textinput)
    listen()
    

getroomname(0)
mainloop()

(This is just a snippet of the main code, so don't worry about the random square it draws in space)


回答1:


It's actually simpler than you're making it, we just need to go about it a little differently. When you run the code below, any key you type should get passed through turtle's event system and printed to the console:

from functools import partial
from turtle import Screen, Turtle

def getroomname():
    temp.penup()
    temp.goto(-150, -60)
    temp.pendown()
    temp.begin_fill()

    for _ in range(2):
        temp.forward(300)
        temp.left(90)
        temp.forward(120)
        temp.left(90)

    temp.end_fill()

def _onkeypress(self, fun, key=None):
    if fun is None:
        if key is None:
            self.cv.unbind("<KeyPress>", None)
        else:
            self.cv.unbind("<KeyPress-%s>" % key, None)
    else:
        def eventfun(event):
            fun(event.char)

        if key is None:
            self.cv.bind("<KeyPress>", eventfun)
        else:
            self.cv.bind("<KeyPress-%s>" % key, eventfun)

def keyinput(key):
    print(key)

screen = Screen()
screen._onkeypress = partial(_onkeypress, screen)  # monkey patch (protected access)

temp = Turtle()
temp.speed('fastest')
temp.fillcolor("white")
temp.width(10)

getroomname()

screen.onkeypress(keyinput)
screen.listen()
screen.mainloop()

I simplified your unrelated code. However, you're not using global correctly so I suggest you review a tutorial about that before you run into trouble. Also, you did from turtle import * but then did def textinput(...) where textinput is also method of Python 3 turtle -- so avoid doing from turtle import * to avoid even more trouble.



来源:https://stackoverflow.com/questions/62805635/why-doesnt-this-monkey-patch-work-for-python-turtle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!