Python在tkinter中一次检测到两个键

时间:2017-03-25 21:32:52

标签: python tkinter

最后想出了如何仅使用tkinter中的键盘滚动屏幕,在右侧网站上找到了答案。现在我还遇到了另一个我遇到的小问题,但却很重要。

程序设置为使用光标键滚动基础图像。如果我同时按下两个键(向上/向左),它将向上滚动一个向左滚动或向上滚动一个向左滚动而不是不断地来回切换。

如何让它认识到我推动两者并将它们压低?它只识别其中一个,无论我按下哪两个键。

import tkinter as tk
import random

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.canvas = tk.Canvas(self, background="bisque", width=400, height=400)
        self.canvas.pack(fill="both", expand=True)
        self.canvas.configure(scrollregion=(-1000, -1000, 1000, 1000))

        self.canvas.bind("<Left>", self.keyleft)
        self.canvas.bind("<Right>", self.keyright)
        self.canvas.bind("<Up>", self.keyup)
        self.canvas.bind("<Down>", self.keydown)
        self.canvas.focus_set()

        # the following two values cause the canvas to scroll
        # one pixel at a time
        self.canvas.configure(xscrollincrement=1, yscrollincrement=1)

        # finally, draw something on the canvas so we can watch it move
        for i in range(1000):
            x = random.randint(-1000, 1000)
            y = random.randint(-1000, 1000)
            color = random.choice(("red", "orange", "green", "blue", "violet"))
            self.canvas.create_oval(x, y, x+20, y+20, fill=color)

    def keyup(self,event):
        self.canvas.yview_scroll(-1,'units')
    def keydown(self,event):
        self.canvas.yview_scroll(1,'units')
    def keyleft(self,event):
        self.canvas.xview_scroll(-1,'units')
    def keyright(self,event):
        self.canvas.xview_scroll(1,'units')

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

1 个答案:

答案 0 :(得分:1)

这不是一个问题;这是你的操作系统处理长按键的方式。转到文本编辑器并按某些键(文本键,而不是箭头),您将看到相同的行为。您的操作系统可能有一些设置来修改该行为。

您可以接管tkinter中的按住行为并以这种方式处理多个键,但这需要首先在您的操作系统中禁用此功能。你是如何做到这一点是特定于操作系统的,我怀疑它是否可以仅为你的应用程序禁用它。

编辑:如果您可以手动或以编程方式关闭操作系统键重复功能,则可以使用此代码让tkinter接管密钥重复:

import tkinter as tk
import random

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.keys = dict.fromkeys(('Left', 'Right', 'Up', 'Down'))

        self.canvas = tk.Canvas(self, background="bisque", width=400, height=400)
        self.canvas.pack(fill="both", expand=True)
        self.canvas.configure(scrollregion=(-1000, -1000, 1000, 1000))

        parent.bind("<KeyPress>", self.keypress)
        parent.bind("<KeyRelease>", self.keypress)
        self.canvas.focus_set()

        # the following two values cause the canvas to scroll
        # one pixel at a time
        self.canvas.configure(xscrollincrement=1, yscrollincrement=1)

        # finally, draw something on the canvas so we can watch it move
        for i in range(1000):
            x = random.randint(-1000, 1000)
            y = random.randint(-1000, 1000)
            color = random.choice(("red", "orange", "green", "blue", "violet"))
            self.canvas.create_oval(x, y, x+20, y+20, fill=color)

        self.looper() # start the looping

    def keypress(self,event):
        if event.keysym in self.keys:
            # event type 2 is key down, type 3 is key up
            self.keys[event.keysym] = event.type == '2'

    def looper(self):
        if self.keys['Up']:
            self.canvas.yview_scroll(-1,'units')
        if self.keys['Down']:
            self.canvas.yview_scroll(1,'units')
        if self.keys['Left']:
            self.canvas.xview_scroll(-1,'units')
        if self.keys['Right']:
            self.canvas.xview_scroll(1,'units')

        self.after(20, self.looper) # set the refresh rate here ... ie 20 milliseconds. Smaller number means faster scrolling

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

编辑编辑:一些谷歌搜索表明某些操作系统发送重复的“按下”按钮&#39;信号而不是我在Linux Mint中看到的新闻发布 - 新闻发布周期。如果您的操作系统确实如此,您可以使用此代码而不禁用自动重复。