wxPython: вызов события вручную - PullRequest
18 голосов
/ 14 апреля 2009

Как я могу вызвать определенное событие вручную из моего собственного кода?

Ответы [ 6 ]

53 голосов
/ 08 мая 2009

Старая тема, но я думаю, что я понял это после того, как запутался в ней в течение длительного времени, поэтому, если кто-нибудь еще придет сюда в поисках ответа, это может помочь.

Чтобы вручную опубликовать событие, вы можете использовать

self.GetEventHandler().ProcessEvent(event)

(wxWidgets документы здесь , wxPython документы здесь )

или

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

( wxWidgets docs , wxPython docs )

, где event - событие, которое вы хотите опубликовать. Создайте событие, например,

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

если вы хотите опубликовать событие EVT_BUTTON. Сделав его PyCommandEvent означает, что он будет распространяться вверх; другие типы событий не распространяются по умолчанию.

Вы также можете создавать собственные события, которые могут переносить любые данные, которые вы хотите, чтобы они. Вот пример:

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

(Я думаю, что я нашел этот код где-то в архиве списка рассылки, но я не могу найти его снова. Если это ваш пример, спасибо! Пожалуйста, добавьте комментарий и возьмите его на себя!)

Итак, чтобы опубликовать пользовательское событие:

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

и вы можете связать его как любое другое событие

self.Bind(EVT_CUSTOM, self.on_event)

и получить пользовательские данные в обработчике событий

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

Или включите пользовательские данные в конструктор событий и сохраните шаг:

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

и т.д.

Надеюсь, это кому-нибудь пригодится.

11 голосов
/ 14 апреля 2009

Я думаю, что вы хотите wx.PostEvent .

В wxPython wiki .

также есть некоторая информация о публикации событий из другого потока для долго выполняющихся задач.
5 голосов
/ 16 ноября 2010

Существует простой и простой способ сделать это с последними версиями wxPython (см. 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)
1 голос
/ 21 июля 2018

Хотя такие методы, как PostEvent и ProcessEvent, упомянутые в других ответах, могут в некотором роде делать это, имейте в виду, что они имеют существенные ограничения:

  • Вы ограничены в том, какие события вы можете легко создать. Например, нет способа создать wx.KeyEvent с конкретным кодом ключа, потому что конструктор не принимает код ключа и нет установщика. Возможно, для этого есть обходные пути (например, создание подклассов KeyEvent), но вам, по сути, придется взломать ограничения фреймворка.
  • Даже для событий, которые вы можете создать, например, событие щелчка, поведение, которое вы получаете от программной отправки события, не будет соответствовать поведению, которое вы получите от фактического выполнения действия от имени пользователя, потому что обработка события native не сработает. Например, программный запуск события щелчка по текстовому полю не даст фокусу текстового поля.

Я бы рекомендовал не использовать PostEvent или ProcessEvent в большинстве случаев. Если вы просто хотите запустить функцию обработки событий, то создание событий вручную бессмысленно; вместо этого просто вызовите функцию явно. Если вы хотите их, потому что вы пытаетесь написать автоматизированный тест пользовательского интерфейса, то вы, вероятно, не собираетесь закончить тем, что удовлетворяет вас из-за ограничений, перечисленных выше; вместо этого я бы рекомендовал написать что-то, что фактически имитирует щелчки и нажатия клавиш на уровне диспетчера ОС / рабочего стола, используя wx.UIActionSimulator. Это своего рода грубое решение, которое возьмет под контроль мышь и клавиатуру вашей системы, что обычно делает такие тесты неподходящими для набора тестов, который вы запускаете на компьютере разработчика ... но по крайней мере он работает , что более чем можно сказать для отправки событий с PostEvent.

0 голосов
/ 05 апреля 2018

Полагаю, это зависит от того, с чем связано ваше событие, но мне нужно было сделать то же самое с LabelFrame, который отображал данные при выборе элемента в списке. Вот как я смог это сделать:

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

Таким образом, всякий раз, когда вы нажимаете на элемент в моем окне «list1_scoring», get_selected_location () запускается, и сведения о выбранном элементе появляются в другом LabelFrame. Мне нужно было вызвать это событие после завершения процесса обновления, чтобы обновить окно отображения. Поэтому я добавил эту строку в конце функции, которая запускает обновление.

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

Это снова запускает get_selected_location (), как будто я только что снова нажал на свой список.

0 голосов
/ 14 апреля 2009

Вы хотите сказать, что хотите отправить событие?

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

В приложении с графическим интерфейсом эта функция отправляет событие по указанному адресу использование объекта wxEvtHandler :: AddPendingEvent. В противном случае отправляет событие немедленно используя wxEvtHandler :: ProcessEvent. Увидеть соответствующая документация для деталей (и предостережения).

Включить файлы

<wx/app.h>

Документы API wxPython

...