Принятие жестов прокрутки мыши в wxPython на Mac OS X

В Mac OS X трекпад поддерживает несколько жестов, одним из которых является смахивание двумя пальцами для прокрутки страницы вверх, вниз, влево или вправо. В wxPython есть панель для создания прокручиваемых виджетов wx.lib.scrolledpanel. Однако у него нет поддержки жестов, что является настоящей болью.

Я попытался изменить NSView, как это делается, если бы это было обычное приложение Objective C, однако NSEvents используют методы (touchesBeganWithEvent: и т. д.), которые являются подклассами для использования в качестве уведомления и обработки события. Это отличается от вызовов Bind в wxPython. Однако это было бы хорошо, если бы Objective C разрешал исправление обезьян... например

def handleTouchBegin(event):
    print "Hey a touch event has begun!"

view.touchBeganWithEvent_ = handleTouchBegin

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

TypeError: cannot change a method

Хорошо, я мог бы сделать то, что говорит яблоко, и подклассифицировать его, но объект уже создан, так как я все еще могу фиксировать события. Конечно есть и

NSEvent addGlobalMonitorForEventsMatchingMask: 
and
NSEvent addLocalMonitorForEventsMatchingMask: 

но они также разочаровывают тем, что либо даже не имеют дело с приложением (глобальные имеют дело со всеми остальными), либо не имеют дело с отдельными событиями NSView (или делают это, и я дезинформирован).

Итак, как мне это сделать? Я пропустил еще один вариант, я знаю, что читал что-то о NSResponder, но из того, что я понял, это то, что такое NSView, ответчик событий, и вы не добавляете его в NSView.

Существуют ли наблюдатели, как в QTKit, например, для наблюдения за изменением состояния загрузки ( apple_ref/doc/uid/TP40008156-CH109-SW11" rel="nofollow">https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/QTKitApplicationProgrammingGuide/AnatomyoftheQTKFramework/AnatomyoftheQTKFramework.html#//apple_ref/ doc/uid/TP40008156-CH109-SW11 )?


person Zimm3r    schedule 09.08.2013    source источник
comment
У вас есть существующее представление, созданное кем-то другим, и вы хотите изменить его обработку событий?   -  person jscs    schedule 09.08.2013
comment
да. Ну, я хочу фиксировать события касания на трекпаде.   -  person Zimm3r    schedule 09.08.2013


Ответы (1)


ObjC не поддерживает обезьянье исправление в стиле Python… но он поддерживает некоторые похожие функции, такие как swizzling методов, создание классов, интерпозиция категорий и т. д. И PyObjC может делать все эти вещи.

На первый взгляд, swizzling из PyObjC должен выглядеть примерно так:

def swizzle(cls, sel, func):
    oldimp = cls.instanceMethodForSelector_(sel)
    def wrapper(self, *args, **kwargs):
        return func(self, oldimp, *args, **kwargs)
    newmethod = objc.selector(wrapper, 
                              selector=oldimp.selector, signature=oldimp.signature)
    objc.classAddMethod(cls, sel, newmethod)
    return wrapper
person abarnert    schedule 09.08.2013
comment
Итак, swizzling заменяет метод или обертывает его (например, вызывает его до или после вызова исходной функции)? - person Zimm3r; 09.08.2013
comment
@Zimm3r: он заменяет метод. Но если вы действительно не знаете об обмане методов ObjC… что ж, думаю, начните здесь и поищите примеры из там, потому что есть много мелких деталей, которые удивят вас, если вы больше разработчик Python, чем разработчик ObjC… - person abarnert; 09.08.2013
comment
Что бы это ни стоило, пару лет назад мне действительно пришлось сделать что-то подобное (используя другую библиотеку, а не wx, и обертывая представление, созданное сторонней библиотекой… но та же основная идея). Мне было проще написать вспомогательную dylib в ObjC, которую мой код Python только что запустил через ctypes в функцию C. Конечно YMMV; это зависит от того, находите ли вы дополнительные уровни PyObjC или синтаксис и цикл редактирования-компиляции-отладки ObjC более обременительными… - person abarnert; 09.08.2013