簡體   English   中英

wxPython:Notebook似乎不適用於多重綁定

[英]wxPython : Notebook seems not to work with multibinding

我正在嘗試創建一個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()

結果是:(如果有人移動滑塊)

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,而不是遵循初始 ID。 handle_forced在one_playing的前三個調用之后調用事件的發生,這就是為什么我得到相同的id的原因。 從3個不同的handle_forced實例中獲得3個這樣的事件是正常的,但是我只得到最后一個。 總而言之,這些id被弄亂了,每個要設置的處理程序只有一個(random?)綁定。 歡迎有足夠耐心的人給我一個解釋。 謝謝!

您基本上將相同的事件類型綁定到相同的窗口小部件3次。 事件發生時,系統將查找綁定,調用它找到的第一個綁定,然后假定已完成並返回。 如果希望系統繼續查找匹配的綁定,則需要在處理函數中調用event.Skip()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM