首页 > 解决方案 > 为什么这个猴子补丁不适用于蟒蛇?

问题描述

所以我正在尝试修补turtle中的onkey函数,以便它调用一个按下按钮的函数,而不是只调用它而不使用任何参数。我正在使用字符串“tester”来查看它是否有效,但看起来原始函数从未改变过。有人可以解释我做错了什么吗?

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

(这只是主要代码的片段,所以不用担心它在空间中绘制的随机正方形)

标签: pythonmonkeypatchingpython-turtle

解决方案


它实际上比你做的更简单,我们只需要稍微改变一下。当你运行下面的代码时,你输入的任何键都应该通过turtle的事件系统并打印到控制台:

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

我简化了你不相关的代码。但是,您没有global正确使用,因此我建议您在遇到麻烦之前查看有关该内容的教程。此外,您做了from turtle import *但后来也做def textinput(...)textinputPython 3 turtle 的方法——所以避免这样做from turtle import *以避免更多的麻烦。


推荐阅读