Различия
Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
fullcircle:32:python_ч_6 [2010/06/19 14:03] |
fullcircle:32:python_ч_6 [2013/10/09 10:33] (текущий) [FrameSecond code:] удаление лишнего кода |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | ======HOW-TO: Программа на Python, Часть 5 ====== | + | ======HOW-TO: Программа на Python, Часть 6 ====== |
<style right> | <style right> | ||
//Автор — Грэг Валтерс (Greg Walters)// | //Автор — Грэг Валтерс (Greg Walters)// | ||
</style> | </style> | ||
+ | |||
- [[..:27:python_ч_1|Программа на Python — часть 1]] | - [[..:27:python_ч_1|Программа на Python — часть 1]] | ||
Строка 13: | Строка 14: | ||
- [[..:34:python_ч_8|Программа на Python — часть 8]] | - [[..:34:python_ч_8|Программа на Python — часть 8]] | ||
- [[..:35:python_ч_9|Программа на Python — часть 9]] | - [[..:35:python_ч_9|Программа на Python — часть 9]] | ||
+ | - [[..:36:python_ч_10|Программа на Python — часть 10]] | ||
+ | - [[..:37:python_ч_11|Программа на Python — часть 11]] | ||
+ | - [[..:38:python_ч_12|Программа на Python — часть 12]] | ||
+ | - [[..:39:python_ч_13|Программа на Python — часть 13]] | ||
+ | - [[..:40:python_ч_14|Программа на Python — часть 14]] | ||
+ | |||
+ | Думаю, что вы поигрались с Boa Constructor со времени нашей последней встречи. Сначала мы напишем простую программу, которая открывает одно окно, а после нажатия кнопки — второе окно. В прошлый раз мы открывали окно сообщений. На этот раз мы откроем отдельное окно. Это будет полезно при создании приложений с несколькими окнами. Итак, приступим... | ||
+ | |||
+ | Запустите Boa Constructor и закройте все вкладки в окне Редактора, кроме вкладок «Командная строка» и «Обзор», нажав клавиши Ctrl-W. Так мы начнём с чистого листа. Создайте новый проект, нажав кнопку «wx.App» (если не помните, как это сделать, обратитесь к предыдущей статье). | ||
+ | |||
+ | До начала работы сохраните «Frame1» под названием «FrameMain.py» и «App1» под названием «Gui2.py». Это очень важно. Выделив вкладку «GUI2» в окне Редактора, перейдите на Панель инструментов, выберите вкладку «Новые» и, щёлкнув кнопку «wx.Frame» (рядом с кнопкой «wx.App»), добавьте ещё одно окно в проект. Убедитесь, что колонка «Модули» на вкладке «Приложение» отображает оба окна. Теперь выделите второе окно и сохраните его под названием «FrameSecond.py»: | ||
+ | |||
+ | Откройте «FrameMain» в режиме Дизайнера. Добавьте новую панель «wx.Panel», измените её размеры, чтобы она закрывала всё окно. Теперь изменим некоторые свойства панели — в прошлый раз мы этого не делали. В окне Инспектора выделите вкладку «Constr», измените заголовок на «Main Frame», а имя — на «FrameMain». Чуть позже мы обсудим правила имён. Измените размер окна на 400x340, нажав на флаговую кнопку «Размер». Она отобразит выпадающий список с полями для высоты и ширины. Измените высоту на 400, а ширину на 340: | ||
+ | |||
+ | {{ :fullcircle:32:screenshot_002.png?350 }} | ||
+ | |||
+ | Щёлкните на вкладке «Props», затем на свойстве «Центрирование» и установите его в «wx.BOTH» Щёлкните по кнопке-галочке (post) для публикации. Запустите приложение, нажав на кнопку с жёлтой стрелкой. Наше приложение появится в центре экрана с заголовком «Main Frame». Закройте окно щелчком на крестике в его правом верхнем углу. | ||
+ | |||
+ | Снова откройте форму «FrameMain» в режиме Дизайнера. Добавьте две кнопки на форму, одну под другой, ближе к центру окна. Выделите верхнюю кнопку, назовите её «btnShowNew», измените надпись на «Show the other frame» на вкладке «Constr» окна Инспектора. С помощью комбинации клавиш Shift+Курсорные стрелки измените размеры кнопки так, чтобы текст был виден полностью, а затем с помощью комбинации клавиш Ctrl+Курсорные стрелки переместите кнопку обратно в центр формы. Выделите нижнюю кнопку, назовите её «btnExit» и измените текст на «Exit». Примените изменения, сохраните файл и запустите приложение, чтобы увидеть изменения. Закройте программу и вернитесь в окно Дизайнера. Мы собираемся добавить обработчиков событий нажатия на кнопки. Выделите верхнюю кнопку, перейдите в окно Инспектора, выделите вкладку «Evts». Нажмите на «ButtonEvent», затем два раза щёлкните по «wx.Evt_BUTTON». Теперь у вас ниже должна появиться строка с надписью «OnBtnShowNewButton». Выделите кнопку «btnExit», повторите операции, убедитесь в том, что вы видите «OnBtnExitButton». Примените и сохраните изменения. Теперь перейдите в окно Редактора и прокрутите код до конца. | ||
+ | |||
+ | Убедитесь, что у вас есть два метода, которые мы создали ранее. Окно должно выглядеть так: | ||
+ | |||
+ | {{ :fullcircle:32:screenshot_003.png?350 }} | ||
+ | |||
+ | Теперь настала пора разобраться со второй формой. Откройте «FrameSecond» в режиме дизайнера. Задайте название «FrameSecond» и заголовок «Second Frame». Задайте центровку «wx.BOTH». Добавьте кнопку и выровняйте её в нижней части окна. Задайте название «btnFSExit» и заголовок «Exit». Создайте событие для кнопки. Добавьте элемент управления «wx.StaticText» в верхней части окна ближе к середине. Назовите его «stHiThere», задайте надпись «Hi there...I'm the second form!», начертание «Sans», размер 14 пт и плотность «wxBOLD»(Props->Font). Теперь сбросьте положение, чтобы в форме кнопка была выровнена справа и слева. Это можно сделать, сняв галочку с атрибута «Position», и изменять положение «X» для сдвига кнопки вправо и влево, и положение «Y» для сдвига кнопки вверх и вниз до тех пор, пока результат не удовлетворит вас. Запишите изменения и сохраните их. | ||
+ | |||
+ | После того как мы создали формы, мы напишем код, который «склеит» их все. | ||
+ | |||
+ | {{ :fullcircle:32:screenshot_004.png?350 }} | ||
+ | |||
+ | В окне Редактора щёлкните на вкладке «GUI2», а затем на вкладке «Код». Под строкой «import FrameMain» добавьте строку «import FrameSecond». Сохраните изменения и перейдите на вкладку «FrameMain». Под строкой «import wx» добавьте строку «import FrameSecond». Прокрутите код вниз до строки «def __init__(self, parent):». Добавьте после строки «self._init_ctrls(parent)» строку «self.Fs = FrameSecond.FrameSecond(self)». В событии «def OnBtnShowNewButton(self, event):» закомментируйте строку «event.Skip()» и добавьте следующие две строки: | ||
+ | |||
+ | <code>self.Fs.Show() | ||
+ | self.Hide()</code> | ||
+ | |||
+ | Наконец, в методе «OnBtnExitButton» закомментируйте строку «event.Skip()» и добавьте строку «self.Close()». | ||
+ | |||
+ | Что всё это делает? Сначала мы убедились, что приложение знает, что у него есть две формы. Поэтому в файле «GUI2» мы импортировали «FrameMain» и «FrameSecond». Затем мы импортировали ссылку на FrameSecond в FrameMain, чтобы позже вызвать второе окно. Мы инициализировали ссылку в методе «_init_», а в методе «OnBtnShowNewButton» приказали кнопке по щелчку на ней отобразить второе окно и спрятать главное окно. Наконец, мы привязали к нажатию на кнопку «Exit» закрытие приложения. | ||
+ | |||
+ | Теперь переключитесь на код окна «FrameSecond». Здесь изменений относительно немного. В методе «_init_» добавьте строку «self.parent = parent», которая добавляет переменную «self.parent». Наконец, в событии щелчка кнопки «FSExitButton» закомментируйте строку «event.Skip()» и добавьте следующие две строки: | ||
+ | |||
+ | <code>self.parent.Show() | ||
+ | self.Hide()</code> | ||
+ | |||
+ | Помните, показывая второе окно, мы спрятали основное, поэтому теперь его надо снова сделать видимым. Затем мы прячем второе окно. Сохраните изменения. | ||
+ | |||
+ | На следующих двух страницах приводится весь получившийся код, чтобы вы могли всё проверить. | ||
+ | |||
+ | Теперь можно запустить программу. Если всё сделано правильно, то после нажатия на кнопку «btnShownNew» первое окно исчезнет, а второе появится. Нажатие на кнопку «Exit» во втором окне закроет его и откроет главное окно. После нажатия на кнопку «Exit» в главном окне программа закроется. | ||
+ | |||
+ | Я обещал, что мы обсудим правила имён. Помните, мы обсуждали комментирование кода? При использовании хорошо структурированных имён для элементов управления ваш код выглядит достаточно документи-*рованным. Если раньше вы просто называли элементы «staticText1» или «button1» или как-то в этом духе, то если вы будете создавать сложные формы с большим количеством элементов управления, в особенности, текстов и кнопок, очень важно, чтобы их имена что-нибудь означали. Если код будет доступен только вам, это не столь важно, но при разработке приложений в коллективе понятные имена элементов управления будут существенным подспорьем. Можно использовать, например, такие имена: | ||
+ | |||
+ | Тип элемента управления — Префикс названия | ||
+ | Статический текст — st_ | ||
+ | Кнопка — btn_ | ||
+ | Поле ввода — txt_ | ||
+ | Флаговая кнопка — chk_ | ||
+ | Радиокнопка — rb_ | ||
+ | Окно — Frm_ или Frame_ | ||
+ | |||
+ | По мере накопления опыта программирования вы можете придумать свои правила для префиксов. Да и у вашего работодателя тоже могут быть определенные требования. | ||
+ | |||
+ | В следующий раз мы отложим в сторону программирование интерфейсов и рассмотрим программирование баз данных. До следующего раза установите на свою систему python-apsw и python-mysqldb. Для SQLite также понадобятся sqlite и sqlitebrowser. Если вы хотите поэкспериментировать с MySql, это прекрасно. Все пакеты устанавливаются с помощью Synaptic. | ||
+ | |||
+ | =====Коды===== | ||
+ | |||
+ | ====GUI2 code:==== | ||
+ | |||
+ | <code>#!/usr/bin/env python | ||
+ | #Boa:App:BoaApp | ||
+ | |||
+ | import wx | ||
+ | |||
+ | import FrameMain | ||
+ | import FrameSecond | ||
+ | |||
+ | modules ={u'FrameMain': [1, 'Main frame of Application', u'FrameMain.py'], | ||
+ | u'FrameSecond': [0, '', u'FrameSecond.py']} | ||
+ | |||
+ | class BoaApp(wx.App): | ||
+ | def OnInit(self): | ||
+ | self.main = FrameMain.create(None) | ||
+ | self.main.Show() | ||
+ | self.SetTopWindow(self.main) | ||
+ | return True | ||
+ | |||
+ | def main(): | ||
+ | application = BoaApp(0) | ||
+ | application.MainLoop() | ||
+ | |||
+ | if __name__ == '__main__': | ||
+ | main()</code> | ||
+ | |||
+ | ====FrameMain code:==== | ||
+ | |||
+ | <code>#Boa:Frame:FrameMain | ||
+ | |||
+ | import wx | ||
+ | import FrameSecond | ||
+ | |||
+ | def create(parent): | ||
+ | return FrameMain(parent) | ||
+ | |||
+ | [wxID_FRAMEMAIN, wxID_FRAMEMAINBTNEXIT, wxID_FRAMEMAINBTNSHOWNEW, | ||
+ | wxID_FRAMEMAINPANEL1, | ||
+ | ] = [wx.NewId() for _init_ctrls in range(4)] | ||
+ | |||
+ | class FrameMain(wx.Frame): | ||
+ | def _init_ctrls(self, prnt): | ||
+ | # generated method, don't edit | ||
+ | wx.Frame.__init__(self, id=wxID_FRAMEMAIN, name=u'FrameMain', | ||
+ | parent=prnt, pos=wx.Point(846, 177), size=wx.Size(400, 340), | ||
+ | style=wx.DEFAULT_FRAME_STYLE, title=u'Main Frame') | ||
+ | self.SetClientSize(wx.Size(400, 340)) | ||
+ | self.Center(wx.BOTH) | ||
+ | |||
+ | self.panel1 = wx.Panel(id=wxID_FRAMEMAINPANEL1, name='panel1', | ||
+ | parent=self, pos=wx.Point(0, 0), size=wx.Size(400, 340), | ||
+ | style=wx.TAB_TRAVERSAL) | ||
+ | |||
+ | self.btnShowNew = wx.Button(id=wxID_FRAMEMAINBTNSHOWNEW, | ||
+ | label=u'Show the other frame', name=u'btnShowNew', | ||
+ | parent=self.panel1, pos=wx.Point(120, 103), size=wx.Size(168, 29), | ||
+ | style=0) | ||
+ | self.btnShowNew.SetBackgroundColour(wx.Colour(25, 175, 23)) | ||
+ | self.btnShowNew.Bind(wx.EVT_BUTTON, self.OnBtnShowNewButton, | ||
+ | id=wxID_FRAMEMAINBTNSHOWNEW) | ||
+ | FrameMain Code (cont.): | ||
+ | self.btnExit = wx.Button(id=wxID_FRAMEMAINBTNEXIT, label=u'Exit', | ||
+ | name=u'btnExit', parent=self.panel1, pos=wx.Point(162, 191), | ||
+ | size=wx.Size(85, 29), style=0) | ||
+ | self.btnExit.SetBackgroundColour(wx.Colour(225, 218, 91)) | ||
+ | self.btnExit.Bind(wx.EVT_BUTTON, self.OnBtnExitButton, | ||
+ | id=wxID_FRAMEMAINBTNEXIT) | ||
+ | |||
+ | def __init__(self, parent): | ||
+ | self._init_ctrls(parent) | ||
+ | self.Fs = FrameSecond.FrameSecond(self) | ||
+ | |||
+ | def OnBtnShowNewButton(self, event): | ||
+ | #event.Skip() | ||
+ | self.Fs.Show() | ||
+ | self.Hide() | ||
+ | |||
+ | def OnBtnExitButton(self, event): | ||
+ | #event.Skip() | ||
+ | self.Close()</code> | ||
+ | |||
+ | ====FrameSecond code:==== | ||
+ | |||
+ | <code>#Boa:Frame:FrameSecond | ||
+ | |||
+ | import wx | ||
+ | |||
+ | def create(parent): | ||
+ | return FrameSecond(parent) | ||
+ | |||
+ | [wxID_FRAMESECOND, wxID_FRAMESECONDBTNFSEXIT, wxID_FRAMESECONDPANEL1, | ||
+ | wxID_FRAMESECONDSTATICTEXT1, | ||
+ | ] = [wx.NewId() for _init_ctrls in range(4)] | ||
+ | |||
+ | class FrameSecond(wx.Frame): | ||
+ | def _init_ctrls(self, prnt): | ||
+ | # generated method, don't edit | ||
+ | wx.Frame.__init__(self, id=wxID_FRAMESECOND, name=u'FrameSecond', | ||
+ | parent=prnt, pos=wx.Point(849, 457), size=wx.Size(419, 236), | ||
+ | style=wx.DEFAULT_FRAME_STYLE, title=u'Second Frame') | ||
+ | self.SetClientSize(wx.Size(419, 236)) | ||
+ | self.Center(wx.BOTH) | ||
+ | self.SetBackgroundStyle(wx.BG_STYLE_COLOUR) | ||
+ | |||
+ | self.panel1 = wx.Panel(id=wxID_FRAMESECONDPANEL1, name='panel1', | ||
+ | parent=self, pos=wx.Point(0, 0), size=wx.Size(419, 236), | ||
+ | style=wx.TAB_TRAVERSAL) | ||
+ | |||
+ | self.btnFSExit = wx.Button(id=wxID_FRAMESECONDBTNFSEXIT, label=u'Exit', | ||
+ | name=u'btnFSExit', parent=self.panel1, pos=wx.Point(174, 180), | ||
+ | size=wx.Size(85, 29), style=0) | ||
+ | self.btnFSExit.Bind(wx.EVT_BUTTON, self.OnBtnFSExitButton, | ||
+ | id=wxID_FRAMESECONDBTNFSEXIT) | ||
+ | |||
+ | self.staticText1 = wx.StaticText(id=wxID_FRAMESECONDSTATICTEXT1, | ||
+ | label=u"Hi there...I'm the second form!", name='staticText1', | ||
+ | parent=self.panel1, pos=wx.Point(45, 49), size=wx.Size(336, 23), | ||
+ | style=0) | ||
+ | self.staticText1.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD, | ||
+ | False, u'Sans')) | ||
+ | |||
+ | def __init__(self, parent): | ||
+ | self._init_ctrls(parent) | ||
+ | self.parent = parent | ||
+ | |||
+ | def OnBtnFSExitButton(self, event): | ||
+ | #event.Skip() | ||
+ | self.parent.Show() | ||
+ | self.Hide()</code> | ||
--------------------------------------- | --------------------------------------- |