2017-07-01 93 views
0

以下代碼在不同環境中的行爲有所不同。Python Turtle按鍵事件不重複

在我的Windows機器上(Windows 10,Python 3.6),每次按鍵都會創建一個響應,然後再次按下某個鍵之前什麼也沒有發生。

關於「Python飾品」(https://trinket.io/python)我不需要重複按鍵,因爲按住鍵可以創建重複事件。

我知道Trinket版本是一個JS實現,但這是否完全解釋了這種差異?程序在Linux或OS上的行爲是否相同?

更重要的是,有沒有辦法使它在Windows上工作,以便按住按鍵創建重複事件?

# import the turtle module so we can use all the neat code it contains 
import turtle 

# Create a variable `tina` that is a Turtle() object. Set shape to 'turtle' 
tina = turtle.Turtle() 
tina.shape('turtle') 

# Create a variable `screen`, a Screen() object, that will handle keyss 
screen = turtle.Screen() 

# Define functions for each arrow key 
def go_left(): 
    tina.left(7) 

def go_right(): 
    tina.right(7) 

def go_forward(): 
    tina.forward(10) 

def go_backward(): 
    tina.backward(10) 

# Tell the program which functions go with which keys 
screen.onkey(go_left, 'Left') 
screen.onkey(go_right, 'Right') 
screen.onkey(go_forward, 'Up') 
screen.onkey(go_backward, 'Down') 

# Tell the screen to listen for key presses 
screen.listen() 
turtle.done() 
+0

你可以嘗試把在那裏的條件設置「真」在while循環的screen.listen()時,鍵被按下並保持'真',直到它被釋放爲止...... –

+0

@Drt,你覺得'screen.listen()'做什麼?它只允許窗口接收事件,並且通常每個程序調用一次(除非正在使用'textinput()'和'numinput()'面板)。它不是停止並等待關鍵事件的東西,也不是可以直接禁用。 – cdlane

回答

0

是有辦法讓它在Windows上工作,讓拿着鑰匙 下創建重複的事件?

按鍵重複是操作系統功能,不同的系統處理它的方式不同。例如,默認情況下,我的Apple OS X系統上的按鍵會重複播放,但我可以進入系統偏好設置/鍵盤並更改速率,甚至關閉它(我試圖測試以下代碼。)

如果您不喜歡「T有鍵重複,想模擬它,下面是一個使用龜定時器事件一鍵啓動的關鍵重複下來,把它關掉關鍵了一個簡單的例子:

# import the turtle module so we can use all the neat code it contains 
from turtle import Turtle, Screen 

KEY_REPEAT_RATE = 20 # in milliseconds 

# Create a variable `tina` that is a Turtle() object. Set shape to 'turtle' 
tina = Turtle('turtle') 

# Create a variable `screen`, a Screen() object, that will handle keys 
screen = Screen() 

# Define functions for each arrow key 
def go_left(): 
    tina.left(7) 
    if repeating: 
     screen.ontimer(go_left, KEY_REPEAT_RATE) 

def go_right(): 
    tina.right(7) 
    if repeating: 
     screen.ontimer(go_right, KEY_REPEAT_RATE) 

def go_forward(): 
    tina.forward(10) 
    if repeating: 
     screen.ontimer(go_forward, KEY_REPEAT_RATE) 

def go_backward(): 
    tina.backward(10) 
    if repeating: 
     screen.ontimer(go_backward, KEY_REPEAT_RATE) 

def start_repeat(func): 
    global repeating 

    repeating = True 

    func() 

def stop_repeat(): 
    global repeating 

    repeating = False 

repeating = False 

# Tell the program which functions go with which keys 
screen.onkeypress(lambda: start_repeat(go_left), 'Left') 
screen.onkeyrelease(stop_repeat, 'Left') 

screen.onkeypress(lambda: start_repeat(go_right), 'Right') 
screen.onkeyrelease(stop_repeat, 'Right') 

screen.onkeypress(lambda: start_repeat(go_forward), 'Up') 
screen.onkeyrelease(stop_repeat, 'Up') 

screen.onkeypress(lambda: start_repeat(go_backward), 'Down') 
screen.onkeyrelease(stop_repeat, 'Down') 

# Tell the screen to listen for key presses 
screen.listen() 

screen.mainloop() 

然而,你的挑戰是當你需要這個模擬重複時,以及當系統已經具有重複能力時 - 弄清楚這兩種情況都會變得混亂。

+0

問題是,如果Chrome應用自動重複,那麼它大概是在系統級啓用的?有沒有一些方法可以在不修改Python代碼的情況下完成這項工作,除了可能是對Screen方法或類似的初始指令? – Robin

+0

@Robin,你不清楚你在問什麼 - 你似乎想要從Python中檢測鍵重複(開,關,未實現)的狀態。這似乎是一個很好的跟進問題。對於我提供的代碼,您可以使用它 - 將'start_repeat()'中的常量'True'更改爲全局布爾變量。如果你想要模擬重複,設置這個變量爲「真」;如果你不需要,則設爲「假」。如果在'start_repeat()'中將'repeat'設置爲'False',則模擬的重複將永遠不會啓動。我相信我回答了問題,或許是時候進行更多的研究和一個新的問題。 – cdlane

+0

我想說的是,我希望代碼在不改變代碼體的情況下「按原樣」工作。它在Trinket版本上運行良好。我不想更改代碼,除了可能在頂部添加一行來指定keydown行爲。或者找到相關的Windows設置(這聽起來沒有希望,因爲它顯然已經設置爲重複關鍵事件,因爲它在Trinket上工作。)。 – Robin

0

好的,我找到了解決方案。

飾品(JS)的實現是不準確的。

使用此代碼:wn.onkey(go_up, "Up")將函數綁定到「標準」Python中的按鍵事件,這意味着函數只被調用一次。

把它重複,而鍵被按下,則需要執行以下操作:

def move(event): 
    my_turtle.forward(5) 

turtle.getcanvas().bind('<Up>', move)