wxPython:笔记本似乎无法使用多重绑定

wxPython:笔记本似乎无法使用多重绑定,wxpython,parameter-passing,wxwidgets,multibinding,wxnotebook,Wxpython,Parameter Passing,Wxwidgets,Multibinding,Wxnotebook,我正在尝试创建一个wxPython应用程序。简化我的设置,假设我有一个左面板和一个右面板。左面板有我的控件,它们是滑块/按钮等。右面板包括一个笔记本,在每个选项卡中,我显示从图像数据列表中获取的视频帧。如果我不使用笔记本,一切正常,控制事件会改变右面板的功能。然而,当我实现笔记本时,在笔记本中的每个面板和每个控件都考虑了多重绑定,我得到了一些奇怪的行为。发生的情况是,每个控件似乎都有不同的父对象,因此我不能在同一个类(!!!)内将变量从一个方法传递到另一个方法。由于问题的复杂性,我无法解释结果。

我正在尝试创建一个wxPython应用程序。简化我的设置,假设我有一个左面板和一个右面板。左面板有我的控件,它们是滑块/按钮等。右面板包括一个笔记本,在每个选项卡中,我显示从图像数据列表中获取的视频帧。如果我不使用笔记本,一切正常,控制事件会改变右面板的功能。然而,当我实现笔记本时,在笔记本中的每个面板和每个控件都考虑了多重绑定,我得到了一些奇怪的行为。发生的情况是,每个控件似乎都有不同的父对象,因此我不能在同一个类(!!!)内将变量从一个方法传递到另一个方法。由于问题的复杂性,我无法解释结果。以下是一个例子:

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()
结果是:(如果有人移动滑块)


我们可以看到,在所有被称为(??)的时间内,on_播放都具有相同的id,而不遵循initid。handle\u forced在一个\u播放的前三次调用之后调用事件,这就是为什么我得到相同的id。从3个不同的handle\u forced实例中得到3次这样的事件是正常的,但我只得到最后一次。总之,ID是混乱的,每个处理程序只需要设置一个(随机?)绑定。欢迎任何有足够耐心的人给我解释。谢谢大家!

基本上是将同一事件类型绑定到同一小部件3次。当事件发生时,系统会查找绑定,调用它找到的第一个绑定,然后假设它已完成并返回。如果希望系统继续查找匹配的绑定,则需要在处理程序函数中调用
event.Skip()。这是追加event.Skip()后的结果对于每个处理程序:
从on_播放14002828262960从on_播放140028262960从on_播放140028262960从handle_强制1400282263568从handle_强制1400282263264从handle_强制140028282262960从handle_强制140028228263568从handle_强制140028228263264从handle28262960
正如您所看到的,on_播放问题仍然存在。也许EVT_PAINT需要另一种方法。顺便说一句,谢谢你一直以来的帮助!其实,只有在启蒙阶段这似乎才发生,我的问题才得以解决,非常感谢!
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