0

J'essaye de créer une application wxPython. Simplifiant mon installation, disons que j'ai un panneau de gauche et un panneau de droite. Le panneau de gauche a mes contrôles, qui sont des curseurs/boutons/etc. Le panneau de droite comprend un bloc-notes dans lequel, dans chaque onglet, j'affiche des images vidéo tirées d'une liste de données d'images. Si je n'utilise pas l'ordinateur portable, tout va bien, les événements de contrôle modifient la fonction du panneau de droite. Cependant, quand j'implémente le cahier, où une multibinding pour chaque panneau à l'intérieur du cahier et chaque commande est considérée, j'obtiens un comportement étrange. Ce qui se passe est que chaque contrôle semble avoir un parent différent, donc je ne peux pas passer des variables à l'intérieur d'une même classe (!!!) d'une méthode à une autre. En raison de la complexité du problème, je ne suis pas en mesure d'interpréter les résultats. Voici un exemple:wxPython: Notebook ne semble pas fonctionner avec la liaison multiple

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() 

qui donne comme résultat: (si quelqu'un déplace le curseur)

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 peut voir que le on_playing a le même identifiant pour tous les temps appelés (? ?), n'obéissant pas à init ids. Le handle_forced appelle les occurrences après les trois premiers appels de one_playing, c'est pourquoi je reçois le même id. Il serait normal d'obtenir 3 occurrences de ce type de 3 différentes instances de handle_forced, mais je ne reçois que le dernier. Dans l'ensemble, les identifiants sont foirés, avec une seule liaison (aléatoire?) Pour chaque gestionnaire à définir. N'importe qui avec assez de patience est invité à me donner une explication. Je vous remercie!

Répondre

1

Vous liez fondamentalement le même type d'événement au même widget 3 fois. Lorsque l'événement se produit, le système recherche une liaison, appelle la première qu'il trouve, puis suppose que c'est fait et retourne. Si vous souhaitez que le système continue de rechercher les liaisons correspondantes, vous devez appeler le event.Skip() dans la fonction de gestionnaire.

+0

Très bien, cela corrige la moitié de mon problème. Ceci est le résultat après l'ajout event.Skip() pour chaque gestionnaire: 'de on_playing 140028228262960 140028228262960 de on_playing de on_playing 140028228262960 140028228263568 de handle_forced de handle_forced 140028228263264 140028228262960 de handle_forced de handle_forced 140028228263568 140028228263264 de handle_forced de handle_forced 140028228262960' –

+0

Le problème on_playing persiste comme vous pouvez le voir. Peut-être que EVT_PAINT a besoin d'une autre approche. Merci pour votre aide jusqu'à maintenant en passant! –

+0

En fait, seulement dans l'initiation cela semble arriver, mon problème est résolu, merci beaucoup! –