2017-06-29 11 views
2

ジョイスティックの入力に応じてボールを移動させるプログラムで作業しています。私が使用しているGUIはTkinterです。クラス外のクラスで生成されたtkinterイベントをバインドします。

最近、私はTkinterの使用方法のデモを発見し、pygameのと互換性があった(これに先立ち、私はpygameのはTkinterのと互換性があったと思いました。私はこれを発見できたとき、私は興奮しました。)

I Find_Joystickクラスで仮想イベント "LT"を定義しました。 (「LT」は、ゲームパッドの「LT」ボタンを指します。)押すと、ボールが左に移動します。しかし、実際の移動機能にイベントをバインドしようとすると、その機能は入力を受け取っていないように見えます。ここで

は私のコードは、(やや単純化された)である:ここでは

from tkinter import * 
import pygame 

class Find_Joystick: 
    def __init__(self, root): 
    self.root = root 

     ## initialize pygame and joystick 
     pygame.init() 
     if(pygame.joystick.get_count() < 1): 
      # no joysticks found 
      print("Please connect a joystick.\n") 
      self.quit() 
     else: 
       # create a new joystick object from 
      # ---the first joystick in the list of joysticks 
      joystick = pygame.joystick.Joystick(0) 
      # tell pygame to record joystick events 
      joystick.init() 

     ## start looking for events 
     self.root.after(0, self.find_events) 

    def find_events(self): 
     ## check everything in the queue of pygame events 
     events = pygame.event.get() 
     joystick = pygame.joystick.Joystick(0) 
     LT = joystick.get_button(6) 
     for event in events: 
      # event type for pressing any of the joystick buttons down 
      if event.type == pygame.JOYBUTTONDOWN: 
      self.root.event_generate('<<JoyFoo>>') 
      if LT == 1: 
       self.root.event_generate('<<LT>>') 

     if event.type == pygame.JOYAXISMOTION: 
      self.root.event_generate('<<JoyMove>>') 
      #Move left 
      if axisX < 0: 
       self.root.event_generate('<<Left>>') 
      #Move right 
      if axisX > 0: 
       self.root.event_generate('<<Right>>') 
      #Move upwards 
      if axisY < -0.008: 
       self.root.event_generate('<<Up>>') 
      #Move downwards 
      if axisY > -0.008: 
       self.root.event_generate('<<Down>>') 

    ## return to check for more events in a moment 
    self.root.after(20, self.find_events) 

def main(): 
## Tkinter initialization 
root = Tk() 
app = Find_Joystick(root) 

frame = Canvas(root, width=500, height = 250) 
frame.pack() 

ball = frame.create_oval([245, 120], [255, 130], outline = 'red', fill = 'red') 



def callback(event): 
    frame.focus_set() 


def moveLeftFunc(event): 
    frame.move(ball, -3, 0) 
    print('Move left') 

frame.bind('<Button-1>', callback) 
frame.bind('<<LT>>', moveLeftFunc) 

root.mainloop() 

if __name__ == "__main__": 
    main() 

は(クラスは、私が使用している主要な部分である)私は、以前に言及していたdemoです。

答えて

0

解決策はイベントバインディングに含まれている可能性があります。 あなたは、フレームのキャンバスにイベントをバインドして、イベントがルートウィジェット(self.root.event_generate('<<LT>>')

によって生成されたそれは、他の方法で働くことができ、イベントが親にではなく、ルートからウィジェットから伝播されています子供のウィジェットに。

あなたが試すことができます:

root.bind('<Button-1>', callback) 
root.bind('<<LT>>', moveLeftFunc) 

(あなたもラインself.root.event_generate('<<JoyFoo>>')を削除する必要があります)

EDIT:

ここでは、ジョイスティックのものなしで再現可能なケースです:

ボタンは、ウィンドウを閉じるためにイベントを伝播しますが、 ルートタイマーがフレームバインディングに近づいて閉じることはありません)

from tkinter import * 
import sys 

def quit(*arg): 
    sys.exit() 

class ChildFrame(Frame): 
    def __init__(self, root): 
    Frame.__init__(self, root) 
    self.grid() 
    button = Button(self, text="Propagate Quit", command=self.child_event) 
    button.pack() 

    def child_event(self): 
    self.event_generate('<<Propagated>>') # triggers the root binding 

root = Tk() 
frame = ChildFrame(root) 

def root_event(*arg): 
    global root 
    root.event_generate('<<NotPropagated>>') # doesn't trigger child binding 
    #root.event_generate('<<Propagated>>') # triggers the root binding 

root.bind('<<Propagated>>', quit)  
frame.bind('<<NotPropagated>>', quit) 

root.after(2000, root_event) # timer to create event from root to child 
root.mainloop() 
関連する問題