HOW-TO: Программа на Python, Часть 6 Сравнение версий

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
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, Часть ​======+======HOW-TO:​ Программа на Python, Часть ​======
 <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>​
  
 --------------------------------------- ---------------------------------------