События и обработка событий под капотом - PullRequest
7 голосов
/ 18 февраля 2011

Я только что работал над несколькими простыми программами, использующими SDL, и это заставило меня вспомнить некоторые написанные мной графические интерфейсы Java.

В простых программах SDL у меня есть цикл, который проверяет любые события (нажатия клавиш, щелчки мыши и т. Д.) И реагирует на них. По сути, это опрос для ввода.

В Java вы присоединяете слушателей к объектам GUI, и слушатели запускаются при возникновении определенных событий.

Мой вопрос заключается в том, обрабатывает ли Java этот цикл опроса в фоновом режиме для нас и решает, например, какой элемент управления GUI был нажат, чтобы он мог вызвать правильного слушателя, или происходит что-то более сложное?

Я знаю, что Qt имеет систему событий, аналогичную Java, где вы используете слоты для подключения обработчика к элементу управления GUI. Это также просто обрабатывает все опросы и определяет, какой элемент был выбран для нас? Или опять что-то более сложное происходит?

UPDATE

Может быть, я не был достаточно ясен с вопросом. Я действительно хочу выяснить, как событие связывает уровень ОС - уровень приложения. Опрашивает ли приложение уровень ОС и извлекает информацию о событиях в приложение? Или у ОС есть какой-либо способ прервать / уведомить приложение о том, что произошло событие, и передать информацию о событии в приложение.

Мне было предложено третье решение, что приложение вызывает блокирующую нативную функцию, такую ​​как:

Event e = someNativeFunction(); // blocks until someNativeFunction() returns an event

Ответы [ 4 ]

5 голосов
/ 18 февраля 2011

"... Java просто обрабатывает этот цикл опроса в фоновом режиме для нас ...?"

В значительной степени, да.Система пользовательского интерфейса предоставляет программе доступ к очереди, которая содержит произошедшие события и цель.Программа проходит через цикл, запрашивая элементы из этой очереди, а затем делает что угодно.Такие библиотеки, как Qt и Java, вызывают в классах виджетов специальные функции, которые сообщают им о том, что произошло событие, так что система может функционировать оттуда, как это предусмотрено API.Для этого библиотека должна преобразовать идентификатор системного окна в класс, управляющий этим виджетом.

Qt предоставляет доступ к этой функции в виде защищенных, виртуальных onXxxxEvent() функций.Стандартное поведение многих виджетов - генерировать сигналы в ответ на события, но это всегда некоторая переведенная форма события, характерная для конкретного виджета.Qt предоставляет вам доступ к этому, так что вы можете переопределить способ, которым виджет обрабатывает событие, или добавить дополнительное поведение для событий, которые он никогда не прослушивал раньше (через подклассы).

Каждая система пользовательского интерфейса немного отличается, но онивсе в основном так же в моем опыте.Здесь мы говорим о сырых win32 и Xlib.

4 голосов
/ 19 февраля 2011

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

Если я правильно помню Windows API (много лет назад), для каждого события была вызвана «оконная функция», и я сделал большой выбор, чтобы выбрать правильное действие в зависимости от типа события.

Я думаю, что большинство наборов инструментов абстрагируют это, как Java AWT с его очередью отправки событий.

Для протокола X входные события (а также «ваше окно должно быть закрашено») поступают в виде сообщений о событиях по проводам, и библиотека инструментария может преобразовать это либо в вызове функции приложения или добавьте их в очередь для последующего запроса.

Протокол X фактически работает (в основном) с двумя байтовыми потоками: один из приложения («клиент») в систему («сервер»), другой в другом направлении. Клиент отправляет пакеты запросов, сервер отправляет обратно результаты (для некоторых типов запросов), ошибки (если какой-либо запрос не может быть выполнен по какой-либо причине) и события (когда что-то происходит на дисплее, например, движение мыши, нажатие клавиши , изменение размера окна, ...).

Для локальных дисплеев в современных системах это обычно реализуется с помощью некоторого механизма общей памяти, но в принципе это может идти через TCP (или сегодня в основном через SSH) для удаленных соединений (таким образом, «по проводам»).

Однажды я начал создавать чистую реализацию клиента Java X (не завершенную, так как нашел другие более интересные вещи), и там я просто использовал Socket с его InputStream и OutputStream для подключения к серверу. Таким образом, в принципе я использовал блокирующую нативную read() функцию Socket-InputStream для ожидания событий (а также результатов и ошибок). Я мог бы использовать java.nio.SocketChannel и в неблокирующем режиме, и тогда, в принципе, у меня был бы цикл опроса (делая другие вещи, между прочим, конечно). (Или я мог бы использовать селектор, ожидая появления новых читаемых данных - таким образом, блокируя тоже.)

Я понятия не имею, какой механизм использует реализация AWT-for-X, используемая реализациями Java для Linux и Solaris, - я полагаю, что они основаны на некотором родном инструментарии, который, в свою очередь, основан на клиентской библиотеке X (для C) "Xlib", но я не знаю, есть ли опрос, блокировка ожидания или , вызываемый кем-то в базе.

2 голосов
/ 18 февраля 2011

Я не знаком с Qt, но на Java в основном да.На практике это становится более сложным, с модальными диалоговыми окнами и тому подобным, но в основном это получение событий от базовой ОС (для клавиатуры и мыши) и публикация их как событий в EventQueue, а различные компоненты получают эти события и используютпотребляйте их или передавайте их по своему усмотрению.

Структура слушателя позволяет компоненту определить, о чем было событие, и передать соответствующую информацию соответствующему слушателю.

1 голос
/ 18 февраля 2011

Это самый старый ресурс, но, между прочим, Java AWT / очередь событий Swing

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...