简体   繁体   English

为什么这个猴子补丁不适用于 python 乌龟?

[英]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.所以我试图在乌龟中修补onkey function,所以它会通过按下按钮调用 function 而不是在没有 arguments 的情况下调用它。 I'm using the string "tester" to see if it works, but it looks like the original functions never got changes.我正在使用字符串“tester”来查看它是否有效,但看起来原始函数从未改变过。 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.它实际上比你做的简单,我们只需要 go 稍微不同。 When you run the code below, any key you type should get passed through turtle's event system and printed to the console:当你运行下面的代码时,你输入的任何键都应该通过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()

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.但是,您没有正确使用global ,因此我建议您在遇到麻烦之前查看有关该内容的教程。 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.此外,您from turtle import *做了,但随后做了def textinput(...)其中textinput也是 Python 3 turtle 的方法 - 所以避免from turtle import *做以避免更多麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM