Получение глобальных событий прокрутки с помощью PyObjC

#python #macos #pyobjc

#python #macos #pyobjc

Вопрос:

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

Пример кода был бы отличным…

Комментарии:

1. Не могли бы вы пояснить, что вы подразумеваете под «глобальным событием прокрутки»? Вы хотите узнать, когда перемещается любой произвольный вид прокрутки? (Кстати, у вас когда-нибудь срабатывали эти нажатия на события? Я надеюсь на это.)

2. Я хочу знать, когда пользователь использует прокрутку двумя пальцами на сенсорной панели. Меня не волнует, прокручивается ли что-нибудь на самом деле, мне просто нужно знать, когда и сколько пользователь прокручивает. У меня не работает мой Event Tap… (Я вроде как сдался на некоторое время, пока мне действительно не понадобится заставить это работать. Может быть, я выучу C до этого …)

3. Получение события прокрутки независимо от того, какое приложение активно? Для этого, вероятно, тоже потребуется нажатие на событие… Недавно я возился с этим. Я еще раз попробую разобраться с этим в эти выходные и посмотрю, смогу ли я разобраться в этом до того, как это сделаете вы или кто-то другой.

Ответ №1:

Вы были на правильном пути с NSEvent ! Пока вы не хотите изменять событие, а просто наблюдать за ним, это так же просто, как вызвать addGlobalMonitorForEventsMatchingMask:handler: . Ваше приложение будет получать уведомления через обратный вызов всякий раз, когда событие типа, указанного вами с маской, отправляется в другое приложение. * Аргумент обработчика — это блок, но вам не нужно беспокоиться, потому что с аргументами блока в PyObjC работать практически проще, чем в обычном Obj-C: вы можете передать любой вызываемый объект (функцию, метод, класс и т.д.), А мост обработает все остальное. Это все, что вам нужно сделать:

 def callback(event):
    NSLog(u"%s" % event)

NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSScrollWheelMask, callback)
  

При обратном вызове вы получаете копию фактического события, к которому вы можете запросить такие вещи, как its deltaX или все, что вам нравится.

Обратите внимание, что, как и многие другие интересные методы в AppKit, этот является новым в 10.6 и отсутствует в файле метаданных для более старых (читай: поставляемых Apple) версий PyObjC. Это означает, что если вы попытаетесь создать приложение, используя установку моста по умолчанию, это завершится неудачей. Вам придется использовать более новую версию.


* Если вы хотите, чтобы события публиковались в вашем приложении, вы должны использовать addLocalMonitorForEventsMatchingMask:handler: . К сожалению, один монитор событий не может получить оба события для вашего приложения и для других.

Комментарии:

1. Хорошо, кажется, что это должно сработать, но когда я использую этот код, кажется, что он завершается, как только запускается, и никогда не вызывает функцию обратного вызова. Есть ли цикл выполнения PyObjC, который я должен запустить или что-то в этомроде. Простите меня, если это глупый вопрос…

2. Да, извините, это не полный скрипт. Вам придется поместить это в приложение с графическим интерфейсом или запустить свой собственный цикл выполнения. Кажется, я припоминаю, что у вас была эта часть в одном из ваших предыдущих вопросов, верно?

3. Я новичок в PyObjC, можете ли вы подробнее рассказать о том, как я бы запустил цикл выполнения? В моем предыдущем вопросе я не совсем понимал, что я делаю. 🙂

4. Используете ли вы Xcode? Именно так я всегда использую PyObjC. Если вы создаете приложение Cocoa-Python с использованием шаблонов, вы можете вставить этот код в метод awakeFromNib вашего делегата приложения. Я бы предложил это как наиболее безболезненный метод. Боюсь, PyObjC составляет примерно 2/3 ObjC. Его сложно использовать, не зная фреймворков Cocoa, что означает некоторое знание Objective-C. Создать цикл выполнения вручную… Я не уверен. Я попытаюсь взглянуть на это.

5. Это работает! Я попробовал в Xcode, и все работает, но есть только одна вещь, которую я не понимаю, для чего нужен NSLog? Это просто для того, чтобы посмотреть, работает ли это или есть практическая цель.