2017-08-26 2 views
1

Ich stieß auf ein Problem, bei dem das Ereignis wx.EVT_LEFT_UP falsch zu feuern scheint oder zumindest sehr kontraintuitiv ist.wxpython: Mouse Up-Ereignis wird falsch ausgelöst

Ich möchte eine Funktion aufrufen, wenn ich auf ein Panel herunterklicke, die Taste gedrückt halte und dann eine Funktion feuere, wenn ich auf ein anderes Panel klicke.

Betrachten Sie den folgenden Code ein:

import wx 

class Example(wx.Frame): 
    def __init__(self, *args, **kwargs): 
     super(Example, self).__init__(*args, **kwargs) 

     panel = wx.Panel(self) 

     # left panel 
     lPan = wx.Panel(panel) 
     lPan.SetBackgroundColour('#9C4141') 
     lPan.Bind(wx.EVT_LEFT_DOWN, lambda e, p='left': self.onLeftDown(e, p)) 
     lPan.Bind(wx.EVT_LEFT_UP, lambda e, p='left': self.onLeftUp(e, p)) 

     # right panel 
     rPan = wx.Panel(panel) 
     rPan.SetBackgroundColour('#415C9C') 
     rPan.Bind(wx.EVT_LEFT_DOWN, lambda e, p='right': self.onLeftDown(e, p)) 
     rPan.Bind(wx.EVT_LEFT_UP, lambda e, p='right': self.onLeftUp(e, p)) 

     # box sizer 
     hbox = wx.BoxSizer(wx.HORIZONTAL) 
     hbox.Add(lPan, 1, flag=wx.EXPAND) 
     hbox.Add(rPan, 1, flag=wx.EXPAND) 
     panel.SetSizer(hbox) 

     self.Show() 

    def onLeftDown(self, e, panel): 
     print('Mouse down on {} panel'.format(panel)) 

    def onLeftUp(self, e, panel): 
     print('Mouse up on {} panel'.format(panel)) 

if __name__ == '__main__': 
    app = wx.App() 
    Example(None, title='Down and Up click', size=(200, 150)) 
    app.MainLoop() 

wären dies beispiels mit JavaScript ganz gut, da die Elementbindung an die Events auf Down- und Up-Klicks unabhängig reagieren würde. Hier scheint es jedoch, dass das Up-Ereignis nur für das Panel ausgelöst wird, auf das zuvor geklickt wurde. (siehe Bild).

enter image description here

Wie Sie sehen können, ist das Up-Ereignis für das linke Panel stattdessen für das rechte Fenster gefeuert. Hat jemand eine Erklärung dafür?

+1

Hallo, unter Windows, sowohl auf 2.7/wxPython 2.9 und auf 3.6.2/wxPython 4.0 Ihr Beispiel, wie Sie arbeitet erwartet (unten links/oben rechts). Sie können den [WIT] (https://wiki.wxpython.org/Widget%20Inspection%20Tool) verwenden, den Zwei-Liner einfügen, bevor Sie den Haupt-Loop betreten, zu den Panels navigieren und den Event-Viewer aktivieren, um alle Events zu sehen für die zwei Panels in Echtzeit. – nepix32

+0

Danke für den Hinweis mit dem Inspektor. Ich benutze es und für mich gibt es wirklich keine Mouse-Up-Ereignis (oder andere Ereignisse als Bewegung und Setcursor) auf der rechten Seite nach dem Ziehen. Ich benutze auch die Version wxPython 4 ('4.0.0b1 osx-cocoa (phoenix)', um genau zu sein), es scheint also ein Fehler bei der MacOS-Implementierung zu sein. – Azial

Antwort

1

Wie nepix32 darauf hinwies, könnte dies ein macOS-bezogener Implementierungsfehler sein, daher versuche ich die folgende Problemumgehung.

Maus eingeben und verlassen wird genau erkannt, also denke ich, dass ich diese binden, um das zuletzt eingegebene Feld zu verfolgen und es im Elternteil zu speichern. Für einen Up-Klick auf ein beliebiges Panel behandle ich, was immer ich mit dem gespeicherten Panel machen möchte.

Das ist, was ich meine (wie erwartet funktioniert):

#!/usr/bin/env python 
import wx 
#import wx.lib.inspection 

class Example(wx.Frame): 
    def __init__(self, *args, **kwargs): 
     super(Example, self).__init__(*args, **kwargs) 

     # parent for left and right panels 
     panel = wx.Panel(self) 
     panel.SetBackgroundColour('#759538') 

     self.lastEntered = None 

     hbox = wx.BoxSizer(wx.HORIZONTAL) 
     # setup some child panels 
     for name in ['left', 'middle', 'right']: 
      pan = wx.Panel(panel, name=name) 
      pan.SetBackgroundColour('#404040') 
      # bind events 
      pan.Bind(wx.EVT_LEFT_DOWN, self.onLeftDown) 
      pan.Bind(wx.EVT_LEFT_UP, self.onLeftUp) 
      pan.Bind(wx.EVT_ENTER_WINDOW, self.onEnter) 
      # put in sizer 
      hbox.Add(pan, 1, flag=wx.EXPAND|wx.ALL, border=5) 

     panel.SetSizer(hbox) 
     self.Show() 

    def onLeftDown(self, e): 
     panel = e.GetEventObject() 
     print('Mouse down on '+panel.GetName()) 

    def onLeftUp(self, e): 
     panel = e.GetEventObject() 
     print('Mouse up on '+panel.GetName()) 
     # the actual up panel 
     if self.lastEntered: 
      print('Actual up on '+self.lastEntered.GetName()) 

    def onEnter(self, e): 
     panel = e.GetEventObject() 
     self.lastEntered = panel 
     print('Entered '+panel.GetName()) 

if __name__ == '__main__': 
    app = wx.App() 
    Example(None, title='Down and Up click', size=(200, 150)) 
    #wx.lib.inspection.InspectionTool().Show() 
    app.MainLoop() 

enter image description here

+0

Von dem, was ich feststellen kann, sind die Ereignisse nach Klick auf "down" auf das angeklickte Widget für "Klick" -Zwecke gesperrt. Du hast Recht, dass du 'Enter' und' Leave', 'Motion' usw. bekommst, aber die Maus' hoch' ist immer noch mit dem originalen Maus-Down-Widget verbunden. Sie können dies überprüfen, indem Sie die "Id" oder "Name" des Ereignisses überprüfen. Ihre Lösung wird für zwei Panels funktionieren, weil es beides ist. Wenn Sie jedoch versuchen, Ihre Lösung für mehr als zwei Panels zu implementieren, müssen Sie versuchen, eine Position des Cursors relativ zur Position des Panels zu ermitteln, was kompliziert sein kann. (Linux wx 3.0.2.0 gtk2 (klassisch)) –

+0

Ich habe meine Antwort bearbeitet, um ein Beispiel zu geben. Es funktioniert für mehrere Panels. Könntest du überprüfen, ob das unter Linux funktioniert? Ich brauche das wirklich, um auf allen Desktop-Plattformen zu arbeiten. – Azial

+0

Nein, es schlägt fehl. Eingegeben links, Maus auf der linken Seite, Maus auf der linken Seite, Actual oben links. Wenn Sie auf links klicken und in der Mitte freigeben –

Verwandte Themen