wxPython: appeler un événement manuellement

Comment puis-je appeler un événement spécifique manuellement à partir de mon propre code?

18
demandé sur Ram Rachum 2009-04-14 18:14:27

6 réponses

je pense que vous voulez wx.PostEvent.

il y a aussi des informations sur la publication d'événements à partir d'autres thread pour tâches de longue durée sur le wiki wxPython.

10
répondu John Montgomery 2009-04-14 18:28:22

ancien sujet, mais je pense que j'ai compris cela après avoir été confus à ce sujet pendant un long moment, donc si quelqu'un d'autre vient ici à la recherche de la réponse, cela pourrait aider.

pour poster manuellement un événement, vous pouvez utiliser

self.GetEventHandler().ProcessEvent(event)

(wxWidgets docs ici, wxPython docs ici)

ou

wx.PostEvent(self.GetEventHandler(), event)

( wxWidgets docs, wxPython docs)

event est l'événement que vous voulez afficher. Construire l'événement avec, par exemple,

wx.PyCommandEvent(wx.EVT_BUTTON.typeId, self.GetId())

si vous voulez poster un événement EVT_BUTTON. En faisant un PyCommandEvent signifie qu'il se propagera vers le haut; les autres types d'événements ne se propagent pas par défaut.

Vous pouvez également créer des événements personnalisés qui peuvent transporter toutes les données que vous souhaitez. Voici un exemple:

myEVT_CUSTOM = wx.NewEventType()
EVT_CUSTOM = wx.PyEventBinder(myEVT_CUSTOM, 1)

class MyEvent(wx.PyCommandEvent):
    def __init__(self, evtType, id):
        wx.PyCommandEvent.__init__(self, evtType, id)
        myVal = None

    def SetMyVal(self, val):
        self.myVal = val

    def GetMyVal(self):
        return self.myVal

(je pense que j'ai trouvé ce code dans une archive de liste de diffusion quelque part, mais je n'arrive pas à le trouver encore. Si c'est votre exemple, merci! S'il vous plaît ajouter un commentaire et en tirer profit!)

alors maintenant, pour poster un événement personnalisé:

event = MyEvent(myEVT_CUSTOM, self.GetId())
event.SetMyVal('here is some custom data')
self.GetEventHandler().ProcessEvent(event)

et vous pouvez lier comme n'importe quel autre événement

self.Bind(EVT_CUSTOM, self.on_event)

et obtenir les données personnalisées dans le gestionnaire d'événement

def on_event(self, e):
    data = e.GetMyVal()
    print 'custom data is: {0}'.format(data)

Ou inclure les données personnalisées dans le cas de constructeur et d'économiser une étape:

class MyEvent(wx.PyCommandEvent):
    def __init__(self, evtType, id, val = None):
        wx.PyCommandEvent.__init__(self, evtType, id)
        self.myVal = val

etc.

j'Espère que cela est utile à quelqu'un.

49
répondu David 2011-09-11 15:24:14

Il y a une façon simple et directe de le faire avec les versions récentes de wxPython (voir http://wiki.wxpython.org/CustomEventClasses):

   # create event class
   import wx.lib.newevent
   SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()

   # post it, with arbitrary data attached
   wx.PostEvent(target, SomeNewEvent(attr1=foo, attr2=bar))

   # bind it as usual
   target.Bind(EVT_SOME_NEW_EVENT, target.handler)
5
répondu Dan Lenski 2010-11-15 23:38:17

vous voulez dire que Vous voulez avoir un événement d'expédition?

:: wxPostEvent void wxPostEvent(wxEvtHandler *dest, wxEvent& event)

dans une application GUI, cette fonction événement de messages à la date spécifiée objet à l'aide de wxEvtHandler:: AddPendingEvent. Sinon, elle distribue l'événement immédiatement à l'aide de wxEvtHandler:: ProcessEvent. Voir la documentation respective pour plus de détails (et mises en garde).

fichiers include

<wx/app.h>

wxPython API docs

0
répondu Bjorn Tipling 2009-04-14 14:19:36

je suppose que cela dépend de ce à quoi votre événement est lié, mais j'avais besoin de faire la même chose avec une image label qui affichait des données lorsque vous avez sélectionné un élément dans une liste. C'est la façon dont j'ai été capable de le faire:

'This is the line that binds my function "get_selected_location()"
to the action of selecting an item in my List box.'

self.list1_scoring.bind('<<ListboxSelect>>', self.get_selected_location)

ainsi, chaque fois que vous cliquez sur un élément dans ma boîte 'list1_scoring', get_selected_location() s'exécute et les détails concernant l'élément sélectionné apparaissent dans une autre image Label. J'avais besoin d'appeler cet événement après qu'un processus de mise à jour soit terminé pour rafraîchir ma fenêtre d'affichage. J'Ai Donc ajouté cette ligne à la fin de la fonction qui exécute la mise à jour.

self.get_selected_location('<<ListboxSelect>>')

ceci exécute get_selected_location () encore une fois comme si j'avais cliqué sur ma liste à nouveau.

0
répondu NLee23 2018-04-04 23:09:19

Alors que les méthodes comme PostEvent et ProcessEvent, mentionné dans d'autres réponses, pouvez trier de le faire, être conscients qu'ils ont des limites importantes:

  • vous êtes limité dans les événements que vous pouvez facilement créer. Par exemple, il n'y a aucun moyen de créer un wx.KeyEvent avec un code clé particulier, parce que le constructeur ne prend pas de code clé et il n'y a pas de setter. Peut-être y a-t-il des solutions de rechange pour cela (comme le sous-classement KeyEvent), mais vous avez essentiellement à pirater autour de la les limites du cadre.
  • Même pour les événements que vous créer, comme un événement de clic, le comportement que vous obtenez à partir de par programmation d'envoi de l'événement ne correspond pas au comportement que vous obtenez à partir de l'effectuer réellement l'action en tant qu'utilisateur, parce que le maternelle gestion de l'événement ne se déclenche pas. Par exemple, le lancement programmatique d'un événement de clic sur un champ de texte ne donnera pas l'accent du champ de texte.

je recommande de ne pas utiliser PostEvent ou ProcessEvent dans la plupart des circonstances. Si vous voulez juste faire tourner votre fonction de gestion d'événements, alors la création manuelle d'événements est inutile; au lieu de cela, appelez simplement la fonction explicitement. Si vous les voulez parce que vous essayez d'écrire un test D'UI automatisé, alors vous n'allez probablement pas finir avec quelque chose qui vous satisfait en raison des limites énumérées ci-dessus; à la place, je recommande d'écrire quelque chose qui simule réellement des clics et des touches au niveau du gestionnaire de bureau/OS en utilisant wx.UIActionSimulator. C'est un peu grossier, et prendra le contrôle de la souris et du clavier de votre système, ce qui rend généralement ces tests inappropriés pour une suite de test que vous utilisez sur une machine de développement... mais au moins, il , ce qui est plus que ce que l'on peut dire pour l'envoi d'événements avec PostEvent.

0
répondu Mark Amery 2018-07-21 15:11:48