0

wxPython 응용 프로그램을 만들려고합니다. 셋업을 간소화하기 위해 왼쪽 패널과 오른쪽 패널이 있다고 가정 해 봅시다. 왼쪽 패널에는 슬라이더/버튼/등의 컨트롤이 있습니다. 오른쪽 패널에는 각 탭마다 이미지 데이터 목록에서 가져온 비디오 프레임을 표시하는 전자 필기장이 있습니다. 노트북을 사용하지 않으면 모든 것이 정상이며, 컨트롤 이벤트는 오른쪽 패널의 기능을 변경합니다. 그러나 노트북을 구현할 때 노트북과 각 컨트롤의 각 패널에 대한 멀티 바인드가 고려되는 경우 이상한 동작이 발생합니다. 어떤 일이 일어나는가에 따라 모든 컨트롤이 다른 부모를 가진 것처럼 보이기 때문에 동일한 클래스 (!!!)의 변수를 한 메소드에서 다른 메소드로 전달할 수 없습니다. 문제의 복잡성으로 인해 결과를 해석 할 수 없습니다. 다음은 예이다 : (누군가가 슬라이더를 이동하는 경우)wxPython : 노트북이 멀티 바인딩에서 작동하지 않는 것 같습니다.

from __init__ 139699098836624 
from __init__ 139699098836016 
from __init__ 139699098624232 
from on_playing 139699098836624 
from on_playing 139699098836624 
from on_playing 139699098836624 
from handle_forced 139699098624232 
from on_playing 139699098624232 
from handle_forced 139699098624232 
from on_playing 139699098624232 
from handle_forced 139699098624232 
from on_playing 139699098624232 
from handle_forced 139699098624232 
from on_playing 139699098624232 
from handle_forced 139699098624232 
from on_playing 139699098624232 

하나는 on_playing라는 모든 시간에 동일한 ID를 (것을 볼 수있다 : 결과적으로 제공

import wx 
import numpy as np 


def checkclass(obj, clas): 
    if isinstance(obj, clas) or issubclass(obj.__class__, clas): 
     return 1 
    else: 
     return 0 



def wx_generic_binder(widget, function): 
    ''' 
    TextCtrl(wx.EVT_TEXT) and Slider(wx.EVT_SLIDER) are supported for now. 
    ''' 
    if widget is not None: 
     if checkclass(widget, wx.TextCtrl): 
      widget.Bind(wx.EVT_TEXT, function) 
     elif checkclass(widget, wx.Slider): 
      widget.Bind(wx.EVT_SLIDER, function) 
     else: 
      raise NotImplementedError 
class TopicsNotebook(wx.Notebook): 
    def __init__(self, parent, forced_frame_handler): 
     wx.Notebook.__init__(self, parent) 
     self.pages = [] 
     for count in range(3): 
      self.pages.append(VideoPanel(self,forced_frame_handler)) 
      self.AddPage(self.pages[-1], str(count)) 

class VideoPanel(wx.Panel): 
    ''' 
    A video panel implementation 
    ''' 

    def __init__(self, parent, forced_frame_handler): 
     ''' 
     data is a list of frames. If a frame is missing, 
     the entry is None 
     ''' 
     wx.Panel.__init__(self, parent, wx.NewId()) 
     self.forced_frame_handler = forced_frame_handler 
     wx_generic_binder(self.forced_frame_handler, 
          lambda event: self.handle_forced(event, self) 
         ) 
     self.forced = 0 
     print 'from __init__', id(self) 
     self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) 
     self.Bind(wx.EVT_PAINT, self.on_playing) 
     wx.CallLater(200, self.SetFocus) 
     self.img = None 


    def handle_forced(self, event, parent): 
     self.count = self.forced_frame_handler.GetValue() 
     self.forced = 1 
     print 'from handle_forced', id(self) 
     self.on_playing(None) 
    def on_playing(self, event): 
     print 'from on_playing', id(self) 


class MainFrame(wx.Frame): 
    ''' 
    Main Processing Window 
    ''' 

    def __init__(self, parent, id_, title): 

     wx.Frame.__init__(self, parent, id_, title) 
     self.main_panel = wx.Panel(self, wx.NewId()) 
     self.lft_box = wx.BoxSizer(wx.VERTICAL) 
     self.slider_min = wx.Slider(self.main_panel, -1, 0, 0, 
            99, size=(600, -1), 
            style=wx.SL_VALUE_LABEL) 
     self.lft_box.Add(self.slider_min) 

     self.rgt_box = wx.BoxSizer(wx.VERTICAL) 

     self.nb = TopicsNotebook(self, forced_frame_handler=self.slider_min) 
     self.rgt_box.Add(self.nb, 1, wx.EXPAND | wx.ALL) 
     self.main_panel.Fit() 
     self.main_box = wx.BoxSizer(wx.HORIZONTAL) 
     self.main_box.AddMany([(self.lft_box, 1), 
           (self.rgt_box, 1)]) 
     self.SetSizerAndFit(self.main_box) 
     wx.CallLater(200, self.SetFocus) 

def main(): 
    ''' 
    main function 
    ''' 
    app = wx.App(0) 

    frame = MainFrame(None , -1, 'Data Mining') 
    frame.Show(True) 
    app.MainLoop() 

main() 

? ?), 초기화 ids에 따르지 않아야합니다. handle_forced는 one_playing의 3 번의 첫 번째 호출 이후에 발생을 호출하므로 동일한 ID를 얻습니다. 3 개의 다른 handle_forced 인스턴스에서 3 개의 이러한 occurences를 얻는 것은 정상이지만, 마지막 인스턴스 만 얻고 있습니다. 대체로, id는 엉망이되어, 설정되는 각 핸들러에 대해서 단 하나의 (임의?) 바인딩이있다. 인내심이 충분한 사람이라면 누구든지 설명을 해주실 수 있습니다. 고맙습니다!

답변

1

기본적으로 동일한 위젯에 같은 이벤트 유형을 3 번 바인딩하고 있습니다. 이벤트가 발생하면 시스템은 바인딩을 찾고, 발견 한 첫 번째 호출을 호출 한 다음 바인딩이 완료되었다고 가정합니다. 시스템이 계속 일치하는 바인딩을 찾길 원하면 핸들러 함수에서 event.Skip()을 호출해야합니다.

+0

좋아,이게 내 문제의 절반을 수정합니다. 를 'on_playing 140028228262960 부터 handle_forced 140,028,228,263,264 에서 handle_forced 140,028,228,263,568 에서 handle_forced 140028228262960 에서 handle_forced 140,028,228,263,264 에서 handle_forced 140,028,228,263,568 에서 140028228262960 을 on_playing에서 140028228262960 을 on_playing에서이 각 처리기 event.Skip()를 추가 한 후 결과 handle_forced 140028228262960' –

+0

볼 수 있듯이 on_playing 문제가 계속 발생합니다. EVT_PAINT에는 다른 접근 방법이 필요합니다. 지금까지 도움을 주셔서 감사합니다! –

+0

사실이 문제가 시작될 때만 문제가 해결됩니다. 정말 고마워요! –