2017-03-25 122 views
0

最後に、tkinterのキーボードだけを使って画面をスクロールする方法を知りました。今私はもう一つの小さい、しかし私が経験している重要な問題があります。Pythonはtkinterで一度に2つのキーを検出します

プログラムは、カーソルキーを使用して下にある画像をスクロールするように設定されています。 2つのキー(上/左)を同時に押すと、常に前後に切り替えるのではなく、1つまたは複数のキーを永遠に、または1つ上に、左にずらして永久にスクロールします。

私は両方を押して、それらを押さえていることを認識するにはどうすればよいですか?どちらのキーが押されていても、どちらか一方しか認識しません。

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

これはtkinterの問題ではありません。それはあなたのOSがキーを長押しする方法です。テキストエディタに移動し、いくつかのキー(矢印ではなくテキストキー)を押すと、同じ動作が表示されます。 OSにはおそらくその動作を変更するための設定がいくつかあります。

tkinterでの押し続ける動作を引き継ぎ、そのように複数のキーを処理することもできますが、まずOSでこの機能を無効にする必要があります。あなたはどのようにOS特有のものなのですか?あなたのアプリケーションでのみ無効にすることは可能です。

編集:あなたは、手動またはプログラム的にOSキーリピート機能を遮断してOKであれば、あなたはキーリピートを引き継ぐの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() 

編集編集:いくつかのグーグルが示唆いくつかのOSは、Linux Mintで見られるプレスリリースのプレスリリースサイクルではなく、繰り返し「プレス」シグナルを送信していることを知っています。お使いのOSがそうしている場合は、自動リピートを無効にしないでこのコードを使用することができます。

+0

私はLinux Mintを使用しています。私がGoogle Earthに行ったとき、コンピュータの設定を変更することなく、両方向でうまくスクロールします。それで、なぜ私はこれが非OSソフトウェアの問題であると思ったのですか? – confused

+0

はい、ダミーのようなコードを試す前に上記のコメントを書いています。 Linux Mintで動作します。ありがとう。 – confused

関連する問題