Часть III

Графический пользовательский интерфейс приложений на языке Python

Темы занятий

  1. Введение в графический пользовательский интерфейс Python
  2. Графические объекты библиотеки Tk, I
  3. Графические объекты библиотеки Tk, II
  4. Функции рисования библиотеки Tk, I
  5. Функции рисования библиотеки Tk, II
  6. Функции рисования библиотеки Tk, III
  7. Наборы Мандельброта
  8. Прочие средства

17-й час

Введение в графический пользовательский интерфейс Python

  С этой главы мы начнём знакомство с библиотекой Tkinter, представляющей средства разработки графического пользовательского интерфейса (GUI — Grafical User Interface) в Python. Изучению этой библиотеки будет посвящена почти вся завершающая часть данной книги. Вы увидите, что принципы программирования приложения с графическим пользовательским интерфейсом существенно отличаются от принципов создания программ для работы в режиме командной строки. Поэтому мы начнём занятие с рассмотрения разных моделей программирования и теоретических основ (не беспокойтесь, эти теории не такие уж и сложные). Закончив чтение главы, Вы сможете описать отличия программирования для командной строки и GUI; объяснить, что такое очередь событий и что вообще в программировании понимают под термином события; объяснить, что такое функции обработки событий.

  *Прим. В. Шипкова: в вопросах управления окошками, Python хоть и является интерпретатором, но сделан куда более грамотно, чем скажем Visual Basic.

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

Модель программирования для GUI

  *Прим. В. Шипкова: GUI - graphical user interfase - графический интерфейс пользователя. Собствнно, само окошко с кнопочками и рюшечками. GUI - общепринятое сокращение.

  Я помню, как появился компьютер Lisa компании Apple. Вице-президент компании, в которой я тогда работал, как раз приобрел такой компьютер. Он установил его в общем компьютерном зале, где с ним могли поработать все желающие. Надо сказать, что в этой компании даже секретарши были профессиональными компьютерщиками, поэтому можете себе представить, сколько часов этот компьютер наработал. Безусловно, что и я не мог отказать себе в удовольствии посидеть за этим компьютером и получил массу удовольствия от его интерфейса. Несколькими месяцами позже возникла компания Macintosh, и многие инженеры, ранее просиживавшие за компьютером Lisa, приобрели себе машины этой компании. В то время я не мог себе позволить купить Macintosh, поэтому мой опыт общения с Mac GUI сводился к работе с принтером PostScript, подключенным к единственному компьютеру Маc, приобретенному нашей компанией для общего пользования. Чтобы изучить работу с PostScript, в то лето мне приходилось подолгу задерживаться каждый вечер.

  *Прим. В. Шипкова: PostScript - скриптовыя язык управления принтерами. Питон также является скриптовым языком. Только для всего. ;) На сегодняшний день наибольшим распространением известен PostScript3.

  Много позже, когда уже появилась X Windows, я для работы над одним проектом получил рабочую станцию Sun, которую умиленно называл про себя "спасателем", хотя мои сотрудники упорно называли её "рыболовным крючком". Это было связано с тем, что незадолго до этого у нас в компании возникли серьезные проблемы с программным обеспечением сервера времени.

  *Прим. В. Шипкова: X Window - графический сервер (т. е. специальная фоновая программа) для *nix (Unix, Linux, FreeBSD, OpenBSD, Sun Solaris). В Windows графика встроена в ядро, что на самом деле не такая уж и хорошая идея (хотя незначительный прирост  скорости в графических приложениях отмечается).

Программное обеспечение сервера времени предназначено для поддержания единого системного времени для всех рабочих станций, подключенных к сети. Наша программа хорошо работала в течение нескольких часов, после чего вдруг возникал провал во времени с отставанием на час, а то и больше. В конце концов, нам удалось обнаружить ошибку в коде. Она состояла в том, что в одной из ветвей инструкции if, где предполагалось добавление значения времени, происходило вычитание. Надо сказать, что прежде чем обнаружить ошибку, данный код просматривало как минимум 4 человека, причём по несколько раз, пока один из них не пожертвовал своим временем и не выполнил отладку программы в пошаговом режиме. Только тогда удалось обнаружить, что значение времени, вместо того чтобы прирасти, уменьшилось. Хотя отладка программ на языке Python выполняется гораздо проще, чем при использовании других языков программирования, и мы даже не рассматриваем эту тему в данной книге, запомните эту историю. Часто только выполнение программы в пошаговом режиме (а интерпретатор Python предоставляет эту возможность) позволяет обнаружить недопустимые изменения значений переменных, что и приводит к сбою программы, возможно, даже в другой части кода. Четыре человека, включая меня, пренебрегли этим средством, в результате чего наша компания в течение месяца работала в стрессовом режиме.

  Моя первая программа с интерфейсом GUI подключалась по сети к серверу Морской обсерватории Соединенных Штатов (U.S. Naval Observatory), определяла текущее время, устанавливала системное время на моём компьютере Sun, после чего по этому образцу устанавливала время на всех компьютерах корпоративной сети в обход сбойного программного обеспечения сервера времени. Вот почему свой компьютер я называл спасателем.

  Таким образом, свой первый опыт обращения с графическим пользовательским интерфейсом я получил при работе с X Windows на компьютере Sun (по-моему, это была версия программы X11 2-го выпуска или последний выпуск версии Х10). Работа с графикой оказалась не особенно сложной, но то, над чем мне действительно пришлось поломать голову, так это над парадигмой обработки событий, на чём основана работа любого приложения с GUI. Во всех программах, которые мы написали до сих пор, в основу были положены средства управления логикой выполнения программы. Пользователь запускал программу, после чего программа, основываясь на исходных данных, говорила пользователю, что нужно делать. После выполнения программа автоматически завершалась.

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

  Логика работы программы с командной строкой обычно достаточно прямолинейна. После запуска такая программа оказывается в пункте А, после чего переходит к пункту В, затем к пункту С и т.д. до пункта Z, где происходит её закрытие. Все это записано в ядре программы: начать здесь, перейти туда, завершиться там. Программы с интерфейсом GUI тоже имеют этап инициализации, но ядро программы создаётся совершенно иначе. Как правило, это очень простая модель, которую можно выразить следующим псевдокодом:

while событие:

  ..............

do функции обработки события

  Управление программой основано на анализе событий, а не на инструкциях логики выполнения программы. Может показаться, что это небольшое отличие. В действительности отличие фундаментальное, и скоро Вы в этом убедитесь. Программы командной строки проходят жёстко опредёленную последовательность событий: А, В, С, ..., Z. Программы с интерфейсом GUI автоматически выполняют только этап инициализации, после чего ожидают появление событий, задаваемых пользователем. Поскольку последовательность событий в данном случае зависит только от пользователя, порядок выполнения программы непредсказуем. И наконец, программы GUI завершают свою работу только по команде пользователя. Можно сказать, что основное отличие лежит в предсказуемости выполнения программы. Выполнение программ командной строки жёстко детерминировано (по крайней мере в теории) и зависит только от исходного набора аргументов.

  *Прим. В. Шипкова: строго говоря, и в командной строке, при работе с вариантами действий, например:

   1. Повторить

   2. Выход

реально невозможно предсказать какой пункт выберет пользователь, и уж тем более, какую клавишу он нажмёт. [Такие ушлые пользователи часто являются головной болью программиста] ;) [Впрочем, такие профессиональные ушлые пользователи называются тестеры, им даже иногда приплачивают]  ;)

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

  Как обрабатываются события? Это зависит от системы и конкретного программного обеспечения. Так, в X Windows события перехватываются сервером и передаются отдельным программам-клиентам. Оба приложения, как сервер, так и клиент, в этом случае относятся к так называемому пользовательскому уровню, т.е. они не являются частью операционной системы, а запускаются пользователями. Во всех версиях Windows показ окон интегрирован с самой операционной системой. Программа X Windows не относилась к системе и запускалась как обычная программа поверх операционной системы, как правило, UNIX. Операционная система Macintosh, по крайней мере те ранние версии, с которыми я работал, также содержала встроенную систему показа окон и не имела интерфейса командной строки. Но, насколько я знаю, в более поздних версиях, таких как MacOS X, операционная система и графический интерфейс пользователя были отделены друг от друга. Хотя, честно говоря, я не самый большой специалист по Macintosh.

  *Прим. В. Шипкова: последние версии MacOS X это не иначе, как доработанная FreeBSD. Я бы очень хотел поработать с этой портированной системой на х86 - Apple'вцы обещали...

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

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

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

В UNIX программы с интерфейсом командной строки и асинхронным выполнением называются демонами (daemon). Аналогичные программы в Windows называются службами. Программа поддержки сервера времени, о которой я рассказывал в начале главы, как раз была демоном, запускаемым в UNIX. Соответствующие службы сервера времени доступны в Windows NT. Если разобраться в структуре программного кода демона или службы, то мы увидим всё тот же цикл while, ожидающий поступления событий для обработки.

  *Прим. В. Шипкова: фоновый процесс, выполняющие сервисные функции, я бы предпочёл, всё-таки называть "службой". "Демон" не предполагает действий в интересах системы, и уж тем более по отношению к пользователю. Отдельных людей демоны даже замуровывали. ;)

  Оконные системы, основанные на циклах обработки событий, практически всегда являются асинхронными. Чтобы поддерживать необходимый уровень интерактивности взаимодействия с пользователем, такая система не может позволить себе замирать в ожидании выполнения каждой вызванной функции (хорошо, если выполнение очередной функции вообще когда-нибудь завершится), вместо того чтобы отслеживать текущие перемещения мыши по коврику и нажатия клавиш. Кроме того, многие события протекают в фоновом режиме, оставаясь незаметными для пользователя. К ним можно отнести изменения положений окон на экране, обновление окон и файлов, таких как файлы .ini в системе Windows. Некоторые события вызывают за собой целые цепочки других событий (в терминологии Windows — сообщений), каждое из которых нужно отследить и обработать.

Вам уже встречались такие термины, как выполнение процедур в фоновом режиме и на переднем плане. Эта терминология уходит корнями к самым первым мультипроцессорным компьютерам. В компьютере IBM 360 память подразделялась на две части: переднего плана и фоновую, которые назывались областями памяти. Чтобы программа работала в фоновом режиме, её нужно было особым образом скомпилировать. Фоновые программы выполнялись значительно медленнее, чем программы переднего плана, но и выполнение последних при этом существенно замедлялось. На первых этапах это было допустимо, но с точки зрения современных стандартов такой подход просто невозможен. Стоит напомнить, что самый мощный компьютер IBM 360 имел 256 Кбайт памяти (обратите внимание — килобайт, а не мегабайт), тогда как на моём компьютере сейчас установлено 320 Мбайт ОЗУ.

  Системы Windows 95/98 и Windows NT выполняют в фоновом режиме колоссальную работу по постоянному обновлению системного реестра, который подменил собой большинство файлов .ini. Впрочем, принцип остался тот же: все текущие изменения установок и параметров работы программ заносятся в соответствующие папки реестра все время, пока Вы работаете с компьютером. В отличие от X Windows, которая обслуживала только себя, оставив все системные проблемы на UNIX, системе Windows ещё приходится поддерживать работу клавиатуры, дисплея, жесткого диска и других присоединенных устройств. Ни одна из этих задач не может ожидать, пока Вы доиграете свою партию в "Солитер".

События

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

  Все оконные системы поддерживают взаимодействие монитора с клавиатурой и мышью. Монитор (обычно) является пассивным устройством вывода для показа окон, заставок, часов, панелей задач и других графических объектов. Клавиатура и мышь — это активные устройства. Можно нажать клавишу на клавиатуре, переместить мышь по коврику и щелкнуть её кнопкой. Каждое подобное действие генерирует событие или даже несколько событий. Например, с клавишей клавиатуры связаны события "нажать и отпустить", а также нажатие клавиши в сочетании с нажатой управляющей клавишей <Shift> или <Ctrl>. Изменение положения указателя мыши на экране отслеживается X и Y, где Х указывает смещение по горизонтали, а Y — по вертикали от верхнего левого угла. Какое событие будет вызвано щелчком правой или левой кнопкой мыши, зависит от текущего положения курсора, а также от того, удерживались ли1 в это время нажатыми управляющие клавиши <Shift>, <Ctrl> или <Alt>.

  Поскольку нас интересуют лишь те события, которые можно обрабатывать с помощью Python и функций библиотеки Tkinter, мы не станем рассматривать многочисленные события (их несколько сотен), определённые в системе Windows. Большинство из них недоступны для Python. Если всё же возникнет необходимость в их использовании, следует использовать модуль расширений Марка Хаммонда (Mark Hammond) Win32. Чтобы узнать больше об этом модуле и загрузить его на свой компьютер, посетите узел по адресу http://starship.python.net/crew/mhairanond/.

В табл. 17.1 перечислены события, используемые в Tkinter.

Таблица 17.1. События, поддерживаемые в Tkinter

Событие

Описание

Activate

Данное окно или графический объект становятся активными

ButtonPress, Button

Нажатие первой, второй кнопки мыши, соответственно Buttonl и т.д., Double-Button- 1 —двойной щелчок первой кнопкой мыши. Можно даже задать тройной щелчок: Triple-Button-1

ButtonRelease

Отпускание кнопки мыши

Circulate

Изменение позиции окна или графического объекта в Z-последовательности

Colormap

Изменение цветовой схемы. (По-моему, это событие не происходит в Windows.)

Configure

Изменение размера, формы или положения графического объекта

Deactivate

Данное окно или графический объект перестают быть активными

Destroy

Данный графический объект назначен для удаления

Enter

Указатель мыши пересек границы данного окна или графического объекта (оказался над объектом)

Expose

Некоторые или все окна и графические объекты изменили экспозицию

Focusln

Данный графический объект получил фокус

FocusOut

Данный графический объект потерял фокус

Gravity

Смысл этого события трудно объяснить начинающему программисту

KeyPress, Key

Нажатие клавиши; Кеуа — нажатие клавиши а и т.д.

KeyRelease

Отпускание клавиши

Motion

Перемещение указателя мыши

Map Property Данное окно или графический объект были выведены на экран
Reparent Некоторое свойство (например, цвет) окна или графического объекта было изменено
Unmap Родительским для данного окна/графического объекта стало другое окно/графический объект
Visibility Данное окно или графический объект не были выведены на экран Изменился вид отображения окна: свернуто, восстановлено и т.д.

Leave

Указатель мыши вышел за границы данного окна или графического объекта

  Как видите, набор контролируемых событий достаточно обширный. Но многие из этих событий используются довольно редко. И уж тем более можно утверждать, что в одной программе Вы не будете использовать все события. По мере изучения материала этой части смысл многих событий станет для Вас более понятным. Чтобы программа реагировала на события, нужно зарегистрировать его и написать выполнение функций обработки событий. Если какое-либо событие не будет зарегистрировано в программе, то такое событие пройдёт для программы незамеченным. Регистрация и функции обработки событий будут рассмотрены в следующем разделе.

Функции обработки событий

  Чтобы зарегистрировать событие, сначала нужно создать соответствующий графический объект (в английской терминологии — widget).

  *Прим. В. Шипкова: читается, как виджет (визуальный компонент). Также известно слово "гаджет". Это не от слова "гадить". ;) Гаджетом называют маленькую вещь, выполняющую какую-либо не слабую функцию, например, мр3-плеер.

  Под графическими объектами понимают окна, снабжённые специальными свойствами. Каждый раз, когда запускается программа с графическим пользовательским интерфейсом, на экране появляются связанные с ней графически объекты, ответственные за выполнение различных функций программы. Примерами графических объектов могут быть кнопки, текстовые поля, меню, полосы прокрутки и ярлыки. Окна, которые содержат другие окна меньшего размера, называются родительскими графическими объектами. Родительским для всех окон и графических объектов вашей программы является корневое окно. Все графические объекты имеют свой родительский объект.

  Когда Вы запускаете редактор IDLE, на экране появляется множество графических объектов, например строка меню и раскрывающиеся меню. Программа IDLE полностью написана на Python с использованием компонентов Tkinter. Прежде чем создать свой первый графический объект, Вы должны выполнить операцию инициализации:

from Tkinter import *

root=Tk()

  Эти строки импортируют модуль Tkinter и инициализируют переменную root объектом корневого окна. После того как Вы получили в программе объект корневого окна, можно приступать к созданию графических объектов:

button = Button(root)

  Результат выполнения этого выражения самоочевиден, не так ли? Вы создали объект кнопки button, которая, впрочем, пока что ничего не делает и даже не видна на экране. Следовательно, нам нужно ещё немного поработать над ней. Прежде всего добавим надпись, которая будет отображаться на кнопке при её показе на экране:

button["text"] = "Завершить работу"

  В данном выражении объект кнопки button обрабатывается как словарь. (В действительности это не совсем так, но мы можем представить себе, что кнопка — это словарь, тем более что объект кнопки содержит метод __getattr__(), с которым мы познакомились в главе 13.) Интерпретатор находит в объекте кнопки атрибут "text" и присваивает ему значение "Завершить работу". С этого момента мы видим кнопку на экране, хотя с ней всё ещё не будет связано выполнение никаких функций. Чтобы придать кнопке функциональность, нужно зарегистрировать для неё событие и написать функцию обработки этого события. Вот как это делается:

def die(event):

  sys.exit(0)

 

button.bind("<Buttonl>", die)

  Вот, собственно, и всё! Мы определили функцию die() , затем с помощью метода button.bind() назначили её функцией обработки события щелчка мыши. Метод bind() принимает два параметра. Первый строковый параметр задаёт имя события, которому Вы хотите назначить функцию обработки. Треугольные скобки < и > необходимы в тех случаях, если имя события не соответствует в точности именам, показанным в первом столбце табл. 17.1. Второй параметр указывает имя функции обработки события, которая может принимать единственный параметр — event (событие). Наша функция die() не нуждается ни в каких параметрах, но ниже мы рассмотрим ситуации, когда параметр необходим.

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

def die():

  sys.exit(0)

 

button["command"]=die

  При таком подходе параметр event в функции обработки события никогда не используется.

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

button.pack()

root.mainloop()

  Метод pack() называют менеджером геометрии объекта. Он посылает объекту кнопки сообщение, определяющее её размер таким образом, чтобы она могла вместить назначенную ей надпись. Метод mainloop(), вызванный для корневого окна, говорит примерно следующее: "ОК, я завершил работу по своей настройке и инициализации и теперь готов к приему и обработке событий". Говоря формальным языком, с помошью этого метода мы создали цикл обработки событий, соответствующий рассмотренному ранее псевдокоду бесконечного цикла с оператором while.

  Введите указанные выше строки и сохраните код в файле, например, под именем btn.py. Код полученной программы в полном виде показан в листинге 17.1.

Листинг 17.1. Программа btn.py

#!С:\PYTHON\PYTHON.EXE

 

import sys

from Tkinter import *

 

def die(event):

  sys.exit(0)

 

root=Tk()

button=Button(root)

button["text"]="Quit"

button.bind("<Button-l>", die)

button.pack()

root.mainloop()

  Теперь запустите программу как обычно. Результат показан на рис. 17.1.

Рис. 17.1. Выполнение программы btn.py

  *Прим. В. Шипкова: на самом деле кнопка будет выглядеть иначе. Это связано с изменившейся библиотекой Tk. Кроме того, если Вы захотите использовать русские надписи, то придётся или использовать кодировку utf8, или писать примерно следующее:

  button["text"]=u"Выход"

Символ 'u' говорит о том, что строку следует преобразовать в кодировку Юникод(Unicode).

  Как видите, функции обработки событий в Python мало чем отличаются от обычных функций. В языках С и C++ функции обработки событий значительно сложнее. Это касается как их регистрации, так и выполнения. Ниже показан пример такой функции в языке С.

static void ButtonCallback(Widget W, XtPointer cd, XtPointer dd)

{

   /* Процедура завершения программы. */

   exit(0);

}

 

  А чтобы зарегистрировать событие, в языке С нужно ввести следующую строку:

XtAddCallback(w, XmNactivateCallback, ButtonCallback,(XtPointer)cd);

  Естественно, что выше приведён простейший пример. Обычно код функций обработки событий занимает много строк. Кроме того, потребуется ещё много вспомогательных программных блоков, которые не нужны в Python. Это строки инициализации, определения графического объекта и настройки его свойств. А затем ещё нужно будет самостоятельно написать цикл обработки событий, который, впрочем, можно будет реализовать как простой цикл while. Наконец, Вам нужно скомпилировать полученную программу, прежде чем Вы сможете ею воспользоваться. Напротив, Python, имеющий модуль Tkinter, позволяет выполнить всю необходимую работу в считанные минуты, и перед Вами на экране уже готовый к употреблению полнофункциональный графический объект. Программа на языке С для запуска в X Windows, аналогичная программе btn.ру, заняла бы как минимум сотню строк кода, в котором начинающий допустил бы сотню ошибок.

  *Прим. В. Шипкова: поверьте мне на слово - сотня ошибок на сотню строк в Си - это не метафора. :)))

Резюме

  Мы немного разобрались в принципах создания графического пользовательского интерфейса и в том, чем программы GUI принципиально отличаются от программ командной строки. Кроме того, Вы узнали, что представляют собой события, очереди событий и функции обработки событий. В следующей главе мы подробно познакомимся с графическими объектами, предоставляемыми библиотекой Tkinter.

Практикум

Вопросы и ответы

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

Да, я так думал, но не удержался.

Каким был самый мощный из всех компьютеров модели IBM 360?

  Мне приходилось работать на модели IBM 360/90 с 1 Мбайт оперативной памяти. Насколько я помню, в то время это был крупнейший компьютер во всем округе Вашингтон (Washington DC). Он был настолько большим, что занимал огромный зал, а во время работы выделял столько тепла, что его пришлось снабдить системой водяного охлаждения.

Контрольные вопросы

  1. Какая метафора лучше всего подойдёт для описания работы очереди событий?

    а) Это как стопка тарелок в кафетерии — тарелку, которую последней положил, первой и взял.

    б) Это как верёвка — тянешь за один конец, а на другом конце кто-то орет.

    в) Это как трубка, в которую опускаешь шарик, а на другом конце вынимаешь.

    г) Это как эскалатор — встал и поехал.

  2. Кто определяет, когда должна завершиться программа с интерфейсом GUI?

    а) Программист. Программа завершается, когда сделает всю работу.

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

    в) Операционная система. Как только программа ей надоест, она покажет синий экран смерти.

    г) Пользователь. Когда он завершит работу с программой, то даст команду на закрытие.

  3. Что такое функция обработки событий?

    а) Функция или метод, которые возвращают события.

    б) Зарегистрированные метод или функция, которые вызываются в ответ на указанное событие.

    в) Метод или функция, которые вызывают другую функцию, назначенную данному событию.

    г) Часть операционной системы Windows, разработанная для обработки стандартных событий.

Ответы

  1. в. Лучшей метафорой для описания работы очереди будет трубка, заполненная шариками. Стопка тарелок — это традиционная метафора для описания работы стека (ещё одной стандартной структуры данных). Очередь поддерживает исходный порядок событий. Если событие А предшествовало событию В, то событие А будет первым извлечено из очереди.

  2. г. Когда должна завершиться работа программы с GUI, решает только пользователь. Этим программы GUI отличаются от программ командной строки, которые завершаются автоматически после выполнения всего кода программы.

      *Прим. В. Шипкова: это справедливо, но не совсем. Если пользователь знает, что выполнение операции займёт много времени, например сжатие фильма, то он может поставить галочку "по окончании работы выключить компьютер" (при условии, что такая галочка в программе есть). Тогда не то что программа произвольно закроется, компьютер выключится!

  3. б. Функция обработки события - это зарегистрированные метод или функция, которые вызываются в ответ на указанное событие.

Примеры и задания

  Чтобы больше узнать о том, какими были самые первые компьютеры, посетите домашнюю страницу Дэйва Николса (Dave Nichols) по адресу http://www.geocities.com/SiliconValley/Lakes/5705/360.html. Кстати, о компьютерах. Я как-то видел тенниску, на которой было написано: "Мне удалось создать проблему двухтысячного года". Ну а для тех, кто делает бизнес на компьютерах и программах, проблема 2000-го года состояла в том, что она закончилась.