Розробка застосунку «Піаніно»

ПРАКТИЧНА РОБОТА 16


Завдання:
створити застосунок Піаніно (див. рисунок). У правій частині вікна має виводитись анімаційний фрагмент, а при натисканні на «клавіші» — відтворюватись звуки.

Обладнання: комп’ютер середовищем програмування мовою Python; папки notes (з файлами формату OGG зі звуками нот) і frames (із файлами формату PNG з кадрами анімації)*.

Теоретичні відомості

Один і той самий  можуть викликати декілька різних об’єктів. З’ясуймо, як зробити, щоб результат виклику для кожного об’єкта був іншим. Наприклад, щоб клацання на різних прямокутниках спричиняло відтворення різних звуків.
Під час виклику обробника в нього передається значення (позначмо його event). Воно містить опис події, зокрема й ідентифікатор об’єкта, який спричинив виклик. Дізнатися ідентифікатор об’єкта можна так:
def on_click(event):
     ...
     key_id = event.widget.find_withtag("current")[0]
     ...
Тут ідентифікатор об’єкта збережено в змінній key_id. Його можна використати для подальшого опрацювання події.

Хід роботи

Під час роботи за комп’ютером дотримуйтеся правил безпеки.

1. Запустіть програму IDLE і відкрийте вікно нового файлу.

2. Запрограмуйте створення вікна програми (назва об’єкта root) з заголовком Піаніно і полотном canvas шириною 670 і висотою 230 пікселів.

3. Підготуйте дані та структури даних для малювання клавіш:

• порожні списки, які буде сформовано пізніше: 
keys = []           # Для ідентифікаторів клавіш
sounds = []     # Для імен файлів з відповідними клавішам звуками

4. Створіть функцію для обробки натискання клавіші:
def on_click(event):
     # Дізнаємося ідентифікатор натиснутої клавіші
     key_id = event.widget.find_withtag("current")[0]
     # За ідентифікатором знаходимо ім’я файлу й відтворюємо звук
     playsound(sounds[keys.index(key_id)])

5. Створіть функцію для малювання прямокутника відповідного кольору та налаштування його для відтворення звуку при клацанні:
def PianoKey(x, y, color, soundfile): 
     if color == 'black': w, h = 40, 140    # Розміри чорної клавіші
     else: w, h = 50, 200                                         # Розміри білої клавіші

     key_id = canvas.create_rectangle(x, y, x+w, y+h, fill = color)
     keys.append(key_id)                           # "Запам'ятовуємо" ідентифікатор...
     sounds.append(soundfile)                # та ім'я файлу зі звуком

     canvas.tag_bind(key_id, '<1>', on_click)

6. Для перевірки створеного коду додайте до основної програми команди:
PianoKey(15, 15, 'white', 'do.ogg')       # Пробний виклик
root.mainloop()
Збережіть програму у файлі Практична робота 15 у папці, що містить папки notes і frames.
При клацанні прямокутника має звучати нота до.

7. Замість рядка з пробним викликом запишіть списки параметрів білих клавіш:

• список координат x лівих верхніх кутів клавіш на полотні (координати y — однакові):
coords = [15, 70, 125, 180, 235, 290, 345, 400]

• список імен файлів зі звуками:
slst = ['do.ogg', 're.ogg', 'mi.ogg', 'fa.ogg', 'sol.ogg', 'la.ogg', 'si.ogg', 'do2.ogg']

8. Запишіть цикл для малювання клавіш, описаних у списках coords і slst (від англ. sound list — список звуків):
for key in range(len(coords)):
     PianoKey(coords[key], 15, 'white' if key < 8 else 'black', './notes/'+slst[key])
Перевірте роботу програми: у вікні має з’явитися рядок білих клавіш, кожна з яких «звучить», якщо її клацнути.
Поясніть, як виконується цей цикл.
Доповніть список coords координатами чорних клавіш (47, 102, 212, 267, 322), а список slst — іменами відповідних файлів ('do-d.ogg', 'mi-b.ogg', 'fa-d.ogg', 'sol-d.ogg', 'si-b.ogg').
Перевірте роботу програми.

9. Створіть список імен файлів із кадрами анімації з папки frames (допишіть імена решти графічних файлів):
plst = ['f01.png', 'f02.png', 'f03.png', ... ,'f24.png', 'f25.png']
pfld = './frames/'                # Шлях до папки з зображеннями
Запрограмуйте читання графічних даних у список frms:
frms = []                                 # Читаємо дані зображень із файлів, ...
for name in plst:                 # імена яких у списку flist, у список frms
     frms.append(PhotoImage(file = pfld+name)) 

10. Створіть на полотні зображення на основі графічних даних першого кадру:
cur_frame = 0                      # Номер поточного кадра
img = canvas.create_image(560, 115, image = frms[cur_frame])

11. Створіть функцію, яка неперервно виводитиме кадри анімації з інтервалом 100 мс:
def show_video():
     global cur_frame
     cur_frame = (cur_frame + 1)%len(frms)
     canvas.itemconfig(img, image = frms[cur_frame])
     # Змінюємо малюнок
     root.update()                                  # Оновлюємо зображення полотна
     root.after(100, show_video)     # Повторний виклик функції play()

12. Додайте до програми виклик функції:
show_video()
Випробуйте роботу програми, спробуйте зіграти мелодію.
Які особливості роботи програми ви помітили?
Запропонуйте варіанти вдосконалення програми, спробуйте їх реалізувати.


Зробіть висновок: які можливості відкриває винайдення способів  і зберігання звуку й відео.