Саммерфилд - Программирование на Python 3 (1077331), страница 129
Текст из файла (страница 129)
Мы сохраняем полученное имя файла, очищаем виджет списка и признак наличия изменений и затем производим попытку открыть файл и распаковать его содержимое в словарь ва1Т. Вата. После того как данные будут прочитаны, выполняется обход всех имен закладок и добавление их по очереди в виджет списка.
В заключение в строку состояния выводится информационное сообщение и обновляется текст заголовка окна. оег гыедаы(ве1(, еуептеиопе): тт ве1(.окаутоСапттпае(); ве1(.рагепт.оевтгоу() Это метод последнего пункта в меню Ейе. Мы даем пользователю возможность сохранить имеющиеся изменения. Если при этом пользова- Программы с главным окном тель отменяет операцию, то ничего не происходит и программа продолжит свою работу. В противном случае мы предписываем родительскому виджету уничтожить себя, что приводит к благополучному завершению программы. Если бы нам потребовалось сохранить пользовательские настройки, это можно было бы сделать здесь, непосредственно перед вызовом метода без! гоу(). бег вб!!Абб(ве1Г, .!цпсгв): Гога = АббЕб!!Есгп(ве1(.рагеп!) 1Г Гоги.вссер!еб впб Гоги.паве: ве1(.ба!в[Гоги.паве] = Гоок пг1 яе1Г.
11всцох.бе1е!е(0, ск!и!ег.ЕИВ) Гсг пввв 1п всг!еб(яе1(.ба!в, псу=в!г,1опег) ве1Г. 1!я!Вох. ьпвег!(Гк!и!ег. еиц, паве) вв1Г.бхг!у = Тгпв Этот метод вызывается, если пользователь запрашивает операцию добавления новой закладки (выбором пункта меню Еб(1 — хАбб (Правка — +Добавить), или щелчком на кнопке с изображением ч)~ в панели инструментов, или нажатием комбинации клавиш С1г[+А на клавиатуре).
Класс АббЕб!!Еогз — это наш собственный диалог, который будет описываться в следующем подразделе, а пока нам достаточно знать, что он имеет флаг ассер!еб, который устанавливается в значение Тгое, если пользователь щелкнет на кнопке ОК, и Еа1яе, если пользователь щелкнет на кнопке Сансе[, а также два атрибута, паве и п г1, в которых хранятся имя и адрес Т]ВЬ закладки, добавляемой или редактируемой пользователем. Мы создаем новый экземпляр диалога АббЕб!!Еоге, который тут же появляется на экране как модальный диалог — вследствие чего дальнейшее выполнение приложения блокируется и инструкция 1( Гоги.ассер!еб ... не будет выполнена, пока диалог не будет закрыт.
Если в диалоге АббЕб!1ЕогпГ пользователь щелкнет на кнопке ОК и при этом укажет имя закладки, мы добавляем новую закладку с указанным именем и адресом Т)В[ в словарь яе! Г. ба!а. Затем мы очищаем виджет списка и снова вставляем в него все закладки в отсортированном порядке. Возможно, более эффективно было бы просто вставлять новую закладку сразу в нужное место, но, даже когда имеется несколько сотен закладок, на современной машине различия будут едва заметны.
В конце мы устанавливаем флаг наличия несохраненных изменений, поскольку теперь у нас появилось изменение, которое еще не было сохранено. бвг еб!!Ебхг(ве1Г, *!цпоге): !пбвхвв = ве1Г. 1ппВох.опГВЕ1ВС11оп() !Г по! ьпбехвя пг 1вп(1пбехев) > 1: гв!пгп хпбех = гпбвхев[0] паше = яе1Г.
1!в!Вох.це!(!пбвх) Гоги = АббЕб!!гоги(вв1(.рвгвпс, паве, ве1г.бага[паве]) !Г Гоги.вссвргвб впб Гоги.паве 574 Глава 13. Введение в программирование графического интерфейса ве1(.пата[(сгв.паве) = Гога.пг1 1т тога, паве != паве; Се1 ве1т.пата[паве) ве11. 11втВох. Ое1ете(0, тктптег. ЕВВ) (ог паве тп вогтеп(ве1т.вата, Кеу=втг. 1пнег); ве1(.
1!втвох.!пвегт(тк1птег.еи0, паве) ве1Г.С!гту = Тгпе Редактирование представляет собой немного более сложную операцию, чем добавление новой закладки, потому что сначала нам необходимо отыскать закладку, которую пользователь желает отредактировать. Метод спгве!ест!оп() возвращает список (возможно пустой) позиций всех выделенных элементов в виджете списка. Если выделен только один элемент, мы запоминаем его текст, то есть имя закладки (а также ключ в словаре ве1(. ов!а), которую пользователь собрался отредактировать. Затем создается новый экземпляр диалога Асг)Е0[туога, которому передается имя и адрес Т)КТ. закладки.
После того как диалог будет закрыт, если пользователь указал непустое имя закладки и щелкнул на кнопке ОК, выполняется обновление словаря ве!Т. свтз. Если имя закладки осталось прежним, можно просто установить флаг наличия несохраненных изменений и выйти (в данном случае предполагается, что пользователь изменил только адрес [ТЕЬ), но если имя закладки изменилось, мы удаляем элемент словаря, ключом которого является прежнее имя, очищаем виджет списка и вновь заполняем его информацией о закладках, как мы делали это в методе добавления новой закладки. Сет еп110е1ете(ве1(, *19поге): тпвехев = ве1(. 1цкВох. спгве1есттап() тг пот тпсехев ог 1еп(1псехев) > т. ге!игл 1ппех = 1ппехев[0) паве = ве1(.
11втВох.се!(!паек) 11 тк[птег.веввавеьсх.авкуезпо("Воокаагкв - Ве1ете", "0е1ете '(О)'~".Гогаат(паве)): зе1(. 11втВпх.се1ете(!паек) ве1(. 11втВох.(оспе вет() Се1 ве1(.пата[паве) ве1(.С(гту = Тгпе Чтобы удалить закладку, мы сначала должны отыскать закладку, выбранную пользователем, поэтому данный метод начинается точно так же, как и метод Ма(пт([пеон. ес1!Ес11(). Если была выбрана всего одна закладка, мы выводим диалог, спрашивая пользователя, действительно ли он желает удалить закладку. Если пользователь отвечает утвердительно, функция вызова диалога возвращает значение Тгсе, мы удаляем закладку из виджета списка и из словаря зе1(, вата и устанавливаем флаг наличия несохраненных изменений.
Кроме того, мы возвращаем фокус ввода в виджет списка. Программы с главным окном 575 Се( ео((ВЬохнеЬРаде(зе1Г, *10псге): [псехез = зе1(. 11згВсх.спгзе1есг[оп() [г пс1 1псехез ог 1еп(>псехез) > и гегигп 1поех = 1поехез[0] сг1 = зе1(.сага[зе1(. 1[згВсх.се((зпсех)] КЕЬЬгохзег.ореп пех гаЬ(пг1) Когда пользователь вызывает этот метод, мы отыскиваем выбранную закладку и извлекаем соответствующий адрес 1)КЬ из словаря зе11. Сага. Затем, с помощью функции хеььгохзег.орел пех гаь() из модуля хеЬЬгохзег, мы открываем веб-броузер, передавая ему указанный адрес 1)ВЬ. Если перед этим веб-броузер еще не был открыт, он будет автоматически запущен. арр11са(1оп = (кхпгег тк() рагс = оз.
рагп, )с[п(оз, расо, О[глазе( (11е ), "чаасез/" ) 1Г зуз. р1еГГсгп. иагГзх)тл("х>п"): 1ссп = рагп г "ьоокеагк.>со" арр11саг[оп. 1сопьызар(>соп, сегас1г=троп) е1зе: арр11сас[оп.>сопь1(еар("е" + расп + "ьоскаагк.хьм") хьпоох = Ма1пХ[посх(арр11са(1сп) арр11са(1оп. ргсгссо1("ХМ ОЕ[ЕТЕ Х1МООХ", хьпоох. Г>1еОи11) арр11са(>оп. Ма101сор() Последние строки программы похожи на последние строки в программе т1егез1-Я.руш, которая рассматривалась ранее, за исключением трех различий. Первое различие заключается в том, что когда пользователь щелкнет на кнопке закрытия окна, в программе Воо]сваг]св, в отличие от программы 1п1егев$, будет вызван другой метод.
Другое отличие состоит в том, что в системе Ж[пйочгв метод тсопЬ[геар() имеет дополнительный аргумент, позволяющий указывать пиктограмму по умолчанию, которая будет отображаться в заголовках всех окон приложения — в системах 1]]к[1Х это делать необязательно, так как это происходит автоматически. И последнее различие заключается в том, что мы определяем текст, отображаемый в заголовке окна приложения, внутри методов класса Мз1пИ1поох, а не здесь.
В программе 1пФегевФ заголовок окна программы никогда не изменялся, поэтому было достаточно установить его только один раз, но в программе Воо]сваг]с мы изменяем текст заголовка, включая в него имя текущего файла с закладками. Теперь, когда мы рассмотрели реализацию класса главного окна и программный код, выполняющий инициализацию программы и запускающий цикл обработки событий, можно обратить евое внимание на диалог АСОЕО11Ео ге. 578 Глава 1В. Введение е программирование графического интерфейса что она допускает изменение размера по горизонтали, установив ее вес равным 1.
Если пользователь попытается изменить вертикальный размер диалога, все виджеты сохранят свое положение относительно друг друга и сместятся в центр окна по вертикали. Но если пользователь попытается изменить горизонтальный размер диалога, виджеты ввода имени и адреса Т)ВЬ изменят свой горизонтальный размер, уменьшившись или растянувшись по горизонтали так, чтобы привести свои размеры в соответствие с доступным пространством. ве1Г.ЬСЬС("<Л1С-и>", 1взЬСв ° сдпоге: пвмеЕпсгу.
Тоссе веС()) зе1г.ыпс("<л1с-и>", 1ззьсв сдпоге: ог1епсгу.госпв вес()) ве1Г. Ыпв("<Ветс гп>", зе1Г. ЬК) ве1Г. Ыпв("<Евсаре>", ве1Г. с1све) ве1Г. рготосо1(ГММ 0ЕСЕТЕ И1ИООИ", ве1Г, с1ове) ве1с.дгзЬ вет() ве1т.наст н!пзсгг(ве1Г) Ранее были созданы две метки, г)агле: и 0ЙЕ:, показывающие, что имеются две горячие комбинации клавиш А(С+И и Ай+О, нажатие которых вызывает перемещение фокуса ввода в соответствующий виджет ввода текста. Чтобы подкрепить это конкретной реализацией, мы добавили необходимые привязки клавиш. Вместо прямого вызова метода Тесов веС() мы использовали лямбда-функции, чтобы иметь возможность игнорировать объект события, который автоматически передается в виде аргумента.
Мы также предусмотрели стандартные привязки клавиш (Ел(ег и Евс) для кнопок ОК и Салсе(. Метод рготосо!() использован, чтобы определить, какой метод должен вызываться, когда пользователь попытается покинуть диалог щелчком на кнопке закрытия окна. Оба вызова дгаЬ веС() и наст н!пеон() необходимы, чтобы сделать диалог модальным. лет сК(ве1Г, еуепС=Моле): ве1(.паве = ве1т.пввеЧвг.дет() ве1г.иг1 = ве1г.иг1чаг.дес() ве1с.вссертез = Тгпе ве1(.с1ове() Этот метод будет вызван, если пользователь щелкнет на кнопке ОК (или нажмет клавишу ЕлСег). Он скопирует текст из ассоциированных переменных типа СК1птег. ВС гспдНаг в соответствующие переменные экземпляра (которые создаются только сейчас), в переменную зе1(, ассертед будет записано значение Тгсе и будет вызван метод ве1т.
с1све(), который закроет диалог. Сет с1ове(ве1Г, ечепС=Мспе): ве1с.рвгепт.Госсе веС() ве1Г.Севтгсу() Этот метод вызывается из метода ве1Е. оК( ), а также когда пользователь щелкнет на кнопке закрытия окна или на кнопке Еалсе( (или нажмет 579 В эакл очение клавишу Езс).