Паттерн Observer в wxPython

Я пытаюсь реализовать шаблон проектирования Observer с помощью wxPython. У меня есть приложение для моделирования, которое вычисляет огромное количество данных в фоновом режиме. Иногда я хотел бы отобразить вывод модели в графическом интерфейсе, который представляет собой просто сетку квадратов разных цветов. В других случаях мне нужно выполнить вычисления без отображения графического интерфейса.

Преимущество шаблона наблюдателя заключается в том, что вы можете подключить или не подключить графический интерфейс, просто добавив или удалив одну строку кода, что-то вроде

self.observers.append(MyWxGui())

или похожие. Теперь, чтобы сделать это, мне нужно, чтобы мои вычисления выполнялись в одном потоке, а графический интерфейс wx — в другом. Я пытался сделать это с помощью wxPython, но всегда получаю фатальную ошибку ввода-вывода:

python: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

Я читал руководства по многопоточности в wxPython, такие как http://wiki.wxpython.org/LongRunningTasks, но у всех у них есть Mainloop(), работающий в основном потоке, а затем длительная задача во вторичном потоке, в то время как мне нужно, чтобы это было наоборот. Это связано с тем, что если у меня есть Mainloop() в основном потоке, программа зависает в ожидании какого-либо события из графического интерфейса вместо того, чтобы продолжить вычисление.

Я также увидел, что не могу манипулировать контекстами устройств (DC), такими как ClientDC или PaintDC, в подпотоке, но я запускаю весь код wx внутри одного и того же потока.

Можно ли запустить Mainloop() и весь графический интерфейс wx в своем собственном потоке, который не является потоком основного приложения?

Запуск wxPython 2.8.11.0 на Ubuntu 10.10 Maverick.


person gozzilli    schedule 06.12.2010    source источник
comment
Знаете ли вы (без потоков) реализацию шаблона наблюдателя в (wx)python? Pubsub, как упомянуто ниже, является глобальной вещью издатель-подписчик, и я еще не нашел реализованного шаблона наблюдателя.   -  person virtualnobi    schedule 27.03.2013


Ответы (1)


Если вы читали эту вики-страницу, то должны знать, что вы можете связаться с потоком wx, используя wx.CallAfter, wxCallLater или wx.PostEvent потокобезопасным способом. У меня есть простой учебник здесь:

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

Лично я бы использовал что-то вроде Pubsub + один из методов потокобезопасности, упомянутых выше, для связи с wx MainLoop. Преимущество Pubsub в том, что он может прослушивать сообщения и реагировать на них соответствующим образом. Приведенный выше пример на самом деле показывает один из способов сделать это. Надеюсь, это поможет вам. В противном случае я настоятельно рекомендую присоединиться к списку рассылки wxPython и спросить там: http://groups.google.com/group/wxpython-users/topics?pli=1

person Mike Driscoll    schedule 06.12.2010
comment
Я не думаю, что это отвечает на мой вопрос. С CallAfter и сим. это по-прежнему графический интерфейс, который вызывает модель для продолжения обработки после ее запуска. Моя цель — полностью реализовать шаблон Observer и, следовательно, заставить модель работать без графического интерфейса. Рассмотрим, например, если графический интерфейс был отключен (т. е. пользователь решает запустить программу без графического интерфейса): как будет продолжаться модель, если она ожидает, пока графический интерфейс выдаст команду, вызываемую CallAfter? Модель должна знать, что потенциально существует графический интерфейс, который противоречит идее наблюдателя. - person gozzilli; 20.03.2011
comment
Pubsub работает вне wx, поэтому я думаю, что он подойдет для этого. Или я что-то неправильно понимаю. - person Mike Driscoll; 21.03.2011