wxPython: ręczne wywołanie zdarzenia

Jak wywołać konkretne zdarzenie ręcznie z własnego kodu?

Author: Ram Rachum, 2009-04-14

6 answers

Myślę, że chcesz wx.PostEvent .

Jest też trochę informacji o publikowaniu wydarzeń z innych wątków dla długich zadań na wxPython wiki .

 10
Author: John Montgomery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-14 18:28:22

Stary temat, ale myślę, że mam to rozpracowane po tym, jak byłem zdezorientowany o tym przez długi czas, więc jeśli ktoś inny przyjdzie tutaj szukać odpowiedzi, to może pomóc.

Aby ręcznie opublikować Zdarzenie, możesz użyć

self.GetEventHandler().ProcessEvent(event)

(wxWidgets docs here, wxPython docs here)

Lub

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

(wxWidgets docs, wxPython docs )

Gdzie event jest wydarzeniem, które chcesz opublikować. Skonstruuj Zdarzenie z np.

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

Jeśli chcesz opublikować Zdarzenie EVT_BUTTON. Uczynienie go PyCommandEvent oznacza, że będzie propagował się w górę; inne typy zdarzeń nie propagują się domyślnie.

Możesz również tworzyć niestandardowe zdarzenia, które mogą przenosić dowolne dane. Oto przykład:

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

(myślę, że znalazłem ten kod gdzieś w archiwum listy dyskusyjnej, ale nie mogę go znaleźć ponownie. Jeśli to jest twój przykład, dzięki! Proszę dodać komentarz i wziąć kredyt na to!)

Więc teraz, aby opublikować wydarzenie niestandardowe:

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

I możesz go związać tak jak każde inne wydarzenie

self.Bind(EVT_CUSTOM, self.on_event)

I pobieramy dane niestandardowe w programie obsługi zdarzeń

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

Lub dołącz niestandardowe dane do konstruktora zdarzeń i zapisz krok:

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

Itd.

Mam nadzieję, że to komuś pomoże.
 49
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-11 15:24:14

Jest prosty, prosty sposób, aby to zrobić z najnowszymi wersjami wxPython (zobacz 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
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-15 23:38:17

Masz na myśli, że chcesz mieć dyspozytornię wydarzeń?

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

W aplikacji GUI funkcja ta posts event to the specified dest korzystanie z obiektu Wxevthandler:: AddPendingEvent. W przeciwnym razie wysyła Zdarzenie natychmiastowe użycie Wxevthandler:: ProcessEvent. Zobacz też szczegółowa dokumentacja (i zastrzeżenia).

Dołącz pliki

<wx/app.h>

WxPython API docs

 0
Author: Bjorn Tipling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-14 14:19:36

Przypuszczam, że zależy to od tego, z czym związane jest twoje zdarzenie, ale musiałem zrobić to samo z ramką etykiet, która wyświetla dane Po wybraniu elementu na liście. W ten sposób udało mi się to zrobić:

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

Więc za każdym razem, gdy klikniesz na element w moim polu 'list1_scoring', uruchomiona zostanie funkcja get_selected_location (), a szczegóły dotyczące wybranego elementu pojawią się w innej ramce LabelFrame. Musiałem wywołać to zdarzenie po zakończeniu procesu aktualizacji, aby odświeżyć moje okno wyświetlania. Więc dodałem to linia na końcu funkcji, która uruchamia aktualizację.

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

Uruchamia ponownie get_selected_location (), tak jakbym ponownie kliknął na moją listę.

 0
Author: NLee23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 23:09:19

Podczas gdy metody takie jak PostEvent i ProcessEvent, wymienione w innych odpowiedziach, mogą to zrobić, należy pamiętać, że mają istotne ograniczenia:

  • jesteś ograniczony w tym, co możesz łatwo utworzyć. Na przykład, nie ma sposobu, aby utworzyć wx.KeyEvent z określonym kodem klucza, ponieważ konstruktor nie pobiera kodu klucza i nie ma settera. Może istnieją obejścia tego problemu( np. podklasowanie KeyEvent), ale zasadniczo musisz obejść ograniczenia ramy.
  • nawet w przypadku zdarzeń, które możesz utworzyć, podobnie jak Zdarzenie click, zachowanie, które uzyskasz po programowym wywołaniu zdarzenia, nie będzie pasowało do zachowania, które uzyskasz po faktycznym wykonaniu akcji jako użytkownik, ponieważ natywna obsługa zdarzenia nie zostanie uruchomiona. Na przykład programowe wywołanie zdarzenia kliknięcia na polu tekstowym nie spowoduje wyostrzenia pola tekstowego.

Zalecam używanie PostEvent LUB ProcessEvent w większości sytuacji. Jeśli aby uruchomić funkcję obsługi zdarzeń, ręczne tworzenie zdarzeń jest bezcelowe; zamiast tego po prostu wywołaj tę funkcję jawnie. Jeśli chcesz je, ponieważ próbujesz napisać zautomatyzowany test interfejsu użytkownika, prawdopodobnie nie skończysz z czymś, co cię zadowoli ze względu na ograniczenia wymienione powyżej; zamiast tego polecam napisanie czegoś, co faktycznie symuluje kliknięcia i naciśnięcia klawiszy na poziomie menedżera OS / desktop za pomocą wx.UIActionSimulator. To trochę obrzydliwe i będzie Przejmij kontrolę nad myszą i klawiaturą systemu, co zwykle sprawia, że takie testy są nieodpowiednie dla zestawu testów uruchamianego na maszynie deweloperskiej... ale przynajmniej to Działa , co jest więcej niż można powiedzieć o wysyłaniu zdarzeń za pomocą PostEvent.

 0
Author: Mark Amery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-21 15:11:48