Использование Git; введение в Tkinter
Система контроля версий:
- Хранение
- Версионирование
- Файлов/объектов
Состояний всего корпуса кода
- История изменений
- Возможно, нелинейная (орграф)
Коротко о VCS/DVCS
VCS:
Цикл работы с VCS
Используется централизованный репозиторий на всех
- Синхронизация
- Редактирование / отладка
- Оформление коммита
- Публикация
Проблема: совместная работа над одним корпусом текстов
- Интерференция изменений
- В частности взаимоблокировка merge/push
- Изменения опубликованных исходников задним числом
DVCS
Цикл работы с DVCS
Используется два репозитория на каждого пользователя — локальный и публичный
- Коммит и push разделены
- Чужой код — только pull
- ⇒ «Общий» репозиторий — pull-аггрегатор
Цикл:
- Синхронизация
- Разработка (в цикле)
- Редактировние / отладка
- Оформление коммита
- Сохранение коммита в локальный репозиторий
- Публикация коммитов в публичный репозиторий
Минимальные правила
- Одно изменение — один коммит
- (по возможности не вносящий регрессий)
- Описательные commit message:
Однострочное описание решённой задачи
Много строчное описание проделанной работы
- Ответственная публикация
- (изменения задним числом можно делать в неопубликованнй истории локального репозитория)
Остальные правила (содержимое commit message, ветки, теги и т. п. — определяются дисциплиной разработки)
Пример:
init/clone (развёртывание)
(«проблема зарождения жизни»: создание репозитория для публикации)
pull (синхронизация)
- Разработка
- Редактирование
add (регистрация изменений)
commit (фиксация изменений)
push (публикация)
Технические подробности:
commit -a
Редактор для commit message commit -m
- …
TkInter
Один из самых старых интерфейсных инструментариев
Что смешно, вместе с tcl
1 import tkinter as tk
2
3 class Application(tk.Frame):
4 def __init__(self, master=None):
5 tk.Frame.__init__(self, master)
6 self.grid()
7 self.createWidgets()
8
9 def createWidgets(self):
10 self.quitButton = tk.Button(self, text='Quit', command=self.quit)
11 self.quitButton.grid()
12
13 app = Application()
14 app.master.title('Sample application')
15 app.mainloop()
Принципы:
- Событийный подход (см. лекцию про async!):
Любой элемент UI — прямоугольное окно (виджет)
- Виджеты: кнопки / списки / надписи / окна ввода / …
Пользователь (или приложение) инициирует низкоуровневые события: нажатие кнопок, перемещение мыши, таймер и т. п.
Tk перенаправляет события окнам, превращая их в синтетические события: изменился текст поля ввода, окно потеряло фокус, окно стало видимым (и его надо перерисовать) и т. п.
Полученный поток событий обрабатывается обработчиками, которые зарегистрированы в приложении
- Образующий цикл скрыт
- Виджеты вложены друг в друга, образуя дерево
Размещением виджетов управляет геометрия (geometry manager)
- Классическая проблема: кто определяет размещение виджета — он сам или его родитель?
- (если кто впервые работает с GUI) Много линейного кода: инициализация виджетов, регистрация обработчиков, множественные изменения при обработке событий и т. п.
Особенность: верхнеуровневое окно Tk
- Может неявно появиться
- Может не исчезнуть до останова приложения
Пример побольше (разберём если успеем)
1 import time
2 import tkinter as tk
3
4 class Application(tk.Frame):
5 def __init__(self, master=None):
6 tk.Frame.__init__(self, master)
7 self.grid()
8 self.createWidgets()
9 self.showtime()
10
11 def showtime(self):
12 self.time.set(time.strftime("%c"))
13
14 def createWidgets(self):
15 self.time = tk.StringVar()
16 self.timeButton = tk.Button(self, text='Time', command=self.showtime)
17 self.quitButton = tk.Button(self, text='Quit', command=self.quit)
18 self.timeLabel = tk.Label(self, textvariable=self.time)
19 self.timeButton.grid()
20 self.quitButton.grid(row=0, column=1)
21 self.timeLabel.grid(columnspan=2)
22
23 app = Application()
24 app.master.title('Sample application')
25 app.mainloop()
Д/З
Для получения оценки необходимо создать свой публичный git-репозиторий и зарегистрировать его тут
- Проверить на нём цикл редактирования / коммитов / публикации