简体   繁体   中英

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

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)

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.

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