1

Тема: Піаніно на python

Всім доброго часу доби! Виникла маленька проблема. Є код "піаніно".

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time
from collections import deque

root =Tk()

a = int(10)

global Mylist 
Mylist = deque()

def plus():
    
    global a
    a = int(a)
    a += 30

    c.create_line(0,50,500+a*2,50,width=2,fill="black")
    c.create_line(0,70,500+a*2,70,width=2,fill="black")
    c.create_line(0,90,500+a*2,90,width=2,fill="black")
    c.create_line(0,110,500+a*2,110,width=2,fill="black")
    c.create_line(0,130,500+a*2,130,width=2,fill="black")

     
def do(event):

    c.create_image(0+a,140,image=DO)
    plus()
    
    mixer.init()
    mixer.music.load('1.mp3')
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
    
    
    Mylist.append(do)
    
    
def re(event):
    
    c.create_image(0+a,130,image=RE)
    plus()
    
    mixer.init()
    mixer.music.load('2.mp3')
    mixer.music.play()
    time.sleep(2)
    mixer.music.stop()
    
    Mylist.append(re) 

def mi(event):
    c.create_image(0+a,125,image=RE)
    plus()
    mixer.init()
    mixer.music.load('2.mp3')
    mixer.music.play()
    time.sleep(2)
    mixer.music.stop()
    
    Mylist.append(mi)

def fa(event):
    c.create_image(0+a,118,image=RE)
    plus()
    mixer.init()
    mixer.music.load('2.mp3')
    mixer.music.play()
    time.sleep(2)
    mixer.music.stop()
    
    Mylist.append(fa)
    
def so(event):
    c.create_image(0+a,105,image=RE)
    plus()
    mixer.init()
    mixer.music.load('2.mp3')
    mixer.music.play()
    time.sleep(2)
    mixer.music.stop()
    
    Mylist.append(so)
    
def lu(event):
    c.create_image(0+a,96,image=RE)
    plus()
    mixer.init()
    mixer.music.load('2.mp3')
    mixer.music.play()
    time.sleep(2)
    mixer.music.stop()
    
    Mylist.append(lu)
    
def si(event):
    c.create_image(0+a,86,image=RE)
    plus()
    mixer.init()
    mixer.music.load('2.mp3')
    mixer.music.play()
    time.sleep(2)
    mixer.music.stop()
    
    Mylist.append(si)
    
def bu(event):
    root.destroy()

def play(event):
    for play_note in Mylist:
        play_note(event)
        

A = dict(do=do,re=re,mi=mi,fa=fa,so=so,lu=lu,si=si)

c = Canvas(width=500,height=300,bg="white",cursor="pencil")

c.create_line(0,50,500,50,width=2,fill="black")
c.create_line(0,70,500,70,width=2,fill="black")
c.create_line(0,90,500,90,width=2,fill="black")
c.create_line(0,110,500,110,width=2,fill="black")
c.create_line(0,130,500,130,width=2,fill="black")

pilImage = Image.open("notaall.png")
DO= ImageTk.PhotoImage(pilImage)

pillImageRe = Image.open('notaall.png')
RE = ImageTk.PhotoImage(pillImageRe)

scr = Scrollbar(root)
scr.config(command = c.xview,orient = HORIZONTAL )


but = Button(root,text='Press to destroy window')
but.place(x=0,y=0)
but2 = Button(root,text = 'Press to replay')
but2.place(x =200,y = 0) 
but2.bind('<Button-1>',play)
but.bind('<Button-1>',bu)

root.bind('k',do)
root.bind('s',re)
root.bind('d',mi)
root.bind('f',fa)
root.bind('g',so)
root.bind('h',lu)
root.bind('j',si)
c.pack()
scr.pack()

root.mainloop()

Все працює коректно,за винятком кнопки реплею. Я від неї хочу щоб вона програла всі ноти ще раз,а вона натомість програє лише одну ноту й видає таку помилку. Буду вдячний за пораду

Post's attachments

Безымянный.png 204.26 kb, 211 downloads since 2017-08-08 

2

Re: Піаніно на python

Там червоним по білому написано: ви змінюєте deque під час ітерації по ньому. Дивимося в код: deque в ньому тільки одне (Mylist), ітерація по ньому - теж (рядки 114-115). Тепер самі подивіться, де там змінюється цей deque.
Чому так не можна робити? Бо ітератор не знає, що сталося з MyList, і намагатиметься брати елементи там, де їх, цілком можливо, вже нема.
Скажіть, а вам самому не нудно писати 7 разів один і той самий код? Написали б функцію, що повертає потрібну вам функцію, для відповідної ноти.

Подякували: N1ck, ostap34PHP2

3

Re: Піаніно на python

koala написав:

Там червоним по білому написано: ви змінюєте deque під час ітерації по ньому. Дивимося в код: deque в ньому тільки одне (Mylist), ітерація по ньому - теж (рядки 114-115). Тепер самі подивіться, де там змінюється цей deque.
Чому так не можна робити? Бо ітератор не знає, що сталося з MyList, і намагатиметься брати елементи там, де їх, цілком можливо, вже нема.
Скажіть, а вам самому не нудно писати 7 разів один і той самий код? Написали б функцію, що повертає потрібну вам функцію, для відповідної ноти.

Чесно кажучи,я не зовсім Вас зрозумів. Можете допомогти більш практично?
deque змінюється щорозу як я заходжу в функцію,і тоді проблема в його зміні? Щоб ліквідувати першочергову проблему слід,щоб deque не змінювався?

4

Re: Піаніно на python

У вас є дві окремі дії - відтворення і додавання до списку. Їх, вочевидь, треба зробити окремими функціями (при цьому можна викликати відтворення з додавання). Десь так:

def play_do():
    mixer.init()
    mixer.music.load('1.mp3')
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()

def add_do(event):
    c.create_image(0+a,140,image=DO)
    plus()
    play_do()
    Mylist.append(play_do)

Але ясно, що всі ці "play_щось" відрізняються однією деталлю - файлом. Тобто можна зробити одну функцію play_note з параметром, і саме цей параметр додавати в Mylist.
Що ж до узагальнення add_note, то нам потрібно багато схожих функцій. Потрібно? То створимо їх у функції:

def create_add_note(vert,img,mp3):
    def add(event):
        c.create_image(0+a,vert,image=img) #
        plus()
        play_note(mp3)
        Mylist.append(mp3)
    return add

І тепер можна зробити просто

root.bind('k',create_add_note(140,DO,'1.mp3')
root.bind('s',create_add_note(130,RE,'2.mp3')
і т.д.

А ще краще - проголосити клас для ноти, що міститиме всі ці параметри (висота на малюнку, малюнок, файл, пов'язана клавіша, що там ще треба), створити набір нот і потім все виставляти в циклах.

Подякували: N1ck, 0xDADA11C72

5

Re: Піаніно на python

koala написав:

У вас є дві окремі дії - відтворення і додавання до списку. Їх, вочевидь, треба зробити окремими функціями (при цьому можна викликати відтворення з додавання). Десь так:

def play_do():
    mixer.init()
    mixer.music.load('1.mp3')
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()

def add_do(event):
    c.create_image(0+a,140,image=DO)
    plus()
    play_do()
    Mylist.append(play_do)

Але ясно, що всі ці "play_щось" відрізняються однією деталлю - файлом. Тобто можна зробити одну функцію play_note з параметром, і саме цей параметр додавати в Mylist.
Що ж до узагальнення add_note, то нам потрібно багато схожих функцій. Потрібно? То створимо їх у функції:

def create_add_note(vert,img,mp3):
    def add(event):
        c.create_image(0+a,vert,image=img) #
        plus()
        play_note(mp3)
        Mylist.append(mp3)
    return add

І тепер можна зробити просто

root.bind('k',create_add_note(140,DO,'1.mp3')
root.bind('s',create_add_note(130,RE,'2.mp3')
і т.д.

А ще краще - проголосити клас для ноти, що міститиме всі ці параметри (висота на малюнку, малюнок, файл, пов'язана клавіша, що там ще треба), створити набір нот і потім все виставляти в циклах.

Вау! Дуже дякую,набагато коротше й зрозуміліше аніж мій "код". ДЯКУЮ!

6

Re: Піаніно на python

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time
from collections import deque

root = Tk()

a = int(10)

global Mylist 
Mylist = deque()

def plus():
    
    global a
    a = int(a)
    a += 30

    c.create_line(0,50,500+a*2,50,width=2,fill="black")
    c.create_line(0,70,500+a*2,70,width=2,fill="black")
    c.create_line(0,90,500+a*2,90,width=2,fill="black")
    c.create_line(0,110,500+a*2,110,width=2,fill="black")
    c.create_line(0,130,500+a*2,130,width=2,fill="black")


def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
     
def create_add_note(vert,img,mp3):
    def add(event):
        c.create_image(0+a,vert,image=img) #
        plus()
        play_note(mp3)
        Mylist.append(mp3)
    return add

def bu(event):
    root.destroy()



def play(event):
    for play_note1 in Mylist:
        #play_note1(event)     
        print(play_note1)
  
c = Canvas(width=500,height=300,bg="white",cursor="pencil")

c.create_line(0,50,500,50,width=2,fill="black")
c.create_line(0,70,500,70,width=2,fill="black")
c.create_line(0,90,500,90,width=2,fill="black")
c.create_line(0,110,500,110,width=2,fill="black")
c.create_line(0,130,500,130,width=2,fill="black")

pilImage = Image.open("notaall.png")
DO= ImageTk.PhotoImage(pilImage)

pillImageRe = Image.open('notaall.png')
RE = ImageTk.PhotoImage(pillImageRe)

scr = Scrollbar(root)
scr.config(command = c.xview,orient = HORIZONTAL )


but = Button(root,text='Press to destroy window')
but.place(x=0,y=0)
but2 = Button(root,text = 'Press to replay')
but2.place(x =200,y = 0) 
but2.bind('<Button-1>',play)
but.bind('<Button-1>',bu)

root.bind('a',create_add_note(140,DO,'1.mp3'))
root.bind('s',create_add_note(130,RE,'2.mp3'))
          
c.pack()
scr.pack()

root.mainloop()

Я скоріш за все щось не зрозумів,навіть попри те,що доволі довго намагався вникнути. Ви мала на увазі такий код? Якщо так,то при

print(play_note1)

виплива 1.mp3 або 2.mp3. Прошу пояснити(якщо можете то прямо написати) в чомуу моя помилка. Дійсно хочу зрозуміти,але....

7

Re: Піаніно на python

Так ви не print робіть, а play_note.
І згорніть всі ці create_line з рядків 54-58 у цикл:

for y in range(50,150,20):
    c.create_line(0, y, 500, y, width=2,fill="black")

От зі plus - складніше. Я так розумію, ви хочете розтягнути лінії; натомість, ви сторюєте нові, які на них накладаються. Гм... Рядки 54-58:
staff = [c.create_line(0, y, 500, y, width=2,fill="black") for y in range(50,150,20)]
plus:

def plus():
    global a
    a = int(a)
    a += 30
    for y in range(50,150,20):
        c.coords(staff, 0, y, 500+a*2, y)

Тепер лишилося тільки прибрати глобальні змінні - і код, хоча й імперативний, вже можна буде комусь показувати.

Подякували: N1ck, ostap34PHP2

8

Re: Піаніно на python

koala написав:

Так ви не print робіть, а play_note.
І згорніть всі ці create_line з рядків 54-58 у цикл:

for y in range(50,150,20):
    c.create_line(0, y, 500, y, width=2,fill="black")

От зі plus - складніше. Я так розумію, ви хочете розтягнути лінії; натомість, ви сторюєте нові, які на них накладаються. Гм... Рядки 54-58:
staff = [c.create_line(0, y, 500, y, width=2,fill="black") for y in range(50,150,20)]
plus:

def plus():
    global a
    a = int(a)
    a += 30
    for y in range(50,150,20):
        c.coords(staff, 0, y, 500+a*2, y)

Тепер лишилося тільки прибрати глобальні змінні - і код, хоча й імперативний, вже можна буде комусь показувати.

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time
from collections import deque
 
root = Tk()
 
a = int(10)
 
global Mylist 
Mylist = deque()
 
def plus():
    
    global a
    a = int(a)
    a += 30
 
    for y in range(50,150,20):
        c.create_line(0, y, 500+a, y, width=2,fill="black")
 
def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
    
def create_add_note(vert,img,mp3):
    def add(event):
        c.create_image(0+a,vert,image=img) #
        plus()
        play_note(mp3)
        Mylist.append(mp3)
    return add
 
def bu(event):
    root.destroy()

def play(event):
    for play_note1 in Mylist:     
        #print(play_note1)
        play_note1(event)
  
c = Canvas(width=500,height=300,bg="white",cursor="pencil")
c.pack()
for y in range(50,150,20):
    c.create_line(0, y, 500, y, width=2,fill="black")

pilImage = Image.open("notaall.png")
DO= ImageTk.PhotoImage(pilImage)
 
pillImageRe = Image.open('notaall.png')
RE = ImageTk.PhotoImage(pillImageRe)
 
scr = Scrollbar(root)
scr.config(command = c.xview,orient = HORIZONTAL )
scr.pack() 
 
but = Button(root,text='Press to destroy window')
but.place(x=0,y=0)
but.bind('<Button-1>',bu)

but2 = Button(root,text = 'Press to replay')
but2.place(x =200,y = 0) 
but2.bind('<Button-1>',play)

root.bind('a',create_add_note(140,DO,'1.mp3'))
root.bind('s',create_add_note(130,RE,'2.mp3'))
          
root.mainloop()

Маємо щось таке.
З приводу play_note1(event). Я робив прінт,щоб подивитися,що воно виведе. Воно,як видно з картинки вивело 1.mp3 є видало помилку,що не може викликати строку.

Post's attachments

Безымянный.png 77.95 kb, 171 downloads since 2017-08-09 

Подякували: ostap34PHP1

9

Re: Піаніно на python

koala написав:

можна зробити одну функцію play_note з параметром, і саме цей параметр додавати в Mylist.

def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
N1ck написав:
print(play_note1)
koala написав:

Так ви не print робіть, а play_note.

N1ck написав:
play_note1(event)

Ви оце серйозно?

Подякували: N1ck1

10 Востаннє редагувалося N1ck (09.08.2017 15:46:16)

Re: Піаніно на python

koala написав:
koala написав:

можна зробити одну функцію play_note з параметром, і саме цей параметр додавати в Mylist.

def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
N1ck написав:
print(play_note1)
koala написав:

Так ви не print робіть, а play_note.

N1ck написав:
play_note1(event)

Ви оце серйозно?

Повинно бути так

def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
    Mylist.append(mp3)

плюс виклик для програвання

def play(event):
    for play_note in Mylist:
        play_note(event)     
        #print(play_note)

Так?

11 Востаннє редагувалося koala (09.08.2017 16:43:55)

Re: Піаніно на python

Які саме слова в реченні "так ви не print робіть, а play_note" вам незрозумілі? З якого саме слова (чи з якої комбінації слів) ви зробили висновок, що там має бути event?

І ніколи не питайте, так програма працює чи ні. Ви можете перевірити, так чи ні, значно швидше і надійніше, ніж ми, просто її запустивши. Якщо вам щось не зрозуміло - то питайте про це прямо: що бачите, що очікуєте, і якісь свої міркування чи опис спроб це вирішити. Не змушуйте нас здогадуватися.

Подякували: N1ck1

12 Востаннє редагувалося N1ck (09.08.2017 18:04:06)

Re: Піаніно на python

koala написав:

Які саме слова в реченні "так ви не print робіть, а play_note" вам незрозумілі? З якого саме слова (чи з якої комбінації слів) ви зробили висновок, що там має бути event?

І ніколи не питайте, так програма працює чи ні. Ви можете перевірити, так чи ні, значно швидше і надійніше, ніж ми, просто її запустивши. Якщо вам щось не зрозуміло - то питайте про це прямо: що бачите, що очікуєте, і якісь свої міркування чи опис спроб це вирішити. Не змушуйте нас здогадуватися.

Ок,погоджуюся,я був неправий причому не тільки в цьому.
Є код

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time
from collections import deque
 
root = Tk()
 
a = int(10)
 
global Mylist 
Mylist = deque()
 
def plus():
    
    global a
    a = int(a)
    a += 30
 
    for y in range(50,150,20):
        c.create_line(0, y, 500+a, y, width=2,fill="black")
 
def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
    
    
def create_add_note(vert,img,mp3):
    def add(event):
        c.create_image(0+a,vert,image=img) #
        plus()
        play_note(mp3)
        Mylist.append(mp3)
    return add
 
def bu(event):
    root.destroy()

def play(event):
    for play_note in list( Mylist):     
        
        play_note
  
c = Canvas(width=500,height=300,bg="white",cursor="pencil")
c.pack()
for y in range(50,150,20):
    c.create_line(0, y, 500, y, width=2,fill="black")

pilImage = Image.open("notaall.png")
DO= ImageTk.PhotoImage(pilImage)
 
pillImageRe = Image.open('notaall.png')
RE = ImageTk.PhotoImage(pillImageRe)
 
scr = Scrollbar(root)
scr.config(command = c.xview,orient = HORIZONTAL )
scr.pack() 
 
but = Button(root,text='Press to destroy window')
but.place(x=0,y=0)
but.bind('<Button-1>',bu)

but2 = Button(root,text = 'Press to replay')
but2.place(x =200,y = 0) 
but2.bind('<Button-1>',play)

root.bind('a',create_add_note(140,DO,'1.mp3'))
root.bind('s',create_add_note(130,RE,'2.mp3'))
          
root.mainloop()

Від рядків

def play(event):
    for play_note in Mylist:
        play_note   

Я очікую,що відбудеться повтор. Він не відбувається,помилки також немає.
Якщо написати

def play(event):
    for play_note in Mylist:
        play_note()
 


відбудеться помилка
play_note()
TypeError: 'str' object is not callable

13

Re: Піаніно на python

Добре, опускаємося до рівня дитячого садочка.
Що буде, якщо у виразі

print(play_note1)

зробити замість слова "print" слово "play_note"?

Прихований текст

І ви взагалі знаєте, що таке функція, список, рядок і т.д., чи навмання ліпите шматочки чужого коду докупи в надії, що воно запрацює?

Подякували: N1ck1

14

Re: Піаніно на python

koala написав:

Добре, опускаємося до рівня дитячого садочка.
Що буде, якщо у виразі

print(play_note1)

зробити замість слова "print" слово "play_note"?

Прихований текст

І ви взагалі знаєте, що таке функція, список, рядок і т.д., чи навмання ліпите шматочки чужого коду докупи в надії, що воно запрацює?

Де ви бачите print(play_note)??

Post's attachments

Безымянный.png 178.16 kb, 182 downloads since 2017-08-09 

15

Re: Піаніно на python

Все стоп. Моя помилка. Опустившись до рівня дитячого садочку я зрозумів як має бути.

def play(event):
    for play_note1 in list( Mylist):     
        
        play_note(play_note1)

В цих рядкав доки значення play_note1 в межах Mylist відбувається виклик функції play_note зі значення play_note1.
Дякую,що розжували,сильно туплю

16

Re: Піаніно на python

N1ck написав:

Де ви бачите print(play_note)??

Єдине місце, де воно зустрічається на цій сторінці - ваш допис від 16:44:33. Я жодного разу цього виразу не писав, тому не знаю, чому ви у мене це питаєте.

Прихований текст

Ви в курсі, що Python ніколи не сплутає ідентифікатори, що відрізняються хоча б однією літерою чи цифрою?

Подякували: N1ck1

17

Re: Піаніно на python

koala написав:
N1ck написав:

Де ви бачите print(play_note)??

Єдине місце, де воно зустрічається на цій сторінці - ваш допис від 16:44:33. Я жодного разу цього виразу не писав, тому не знаю, чому ви у мене це питаєте.

Прихований текст

Ви в курсі, що Python ніколи не сплутає ідентифікатори, що відрізняються хоча б однією літерою чи цифрою?

Та ні,цілковито моя помилка. Я сильно затупив в цьому моменті. Дякую,Вам велике.

18

Re: Піаніно на python

Можливо десь колись кому знадобиться щось подібне

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time
from collections import deque
 
root = Tk()
 
a = int(10)
 
global Mylist 
Mylist = deque()
 
def plus():
    
    global a
    a = int(a)
    a += 30
 
    for y in range(50,150,20):
        c.create_line(0, y, 500+a, y, width=2,fill="black")
 
def play_note(mp3):
    mixer.init()
    mixer.music.load(mp3)
    mixer.music.play()
    time.sleep(0.5)
    mixer.music.stop()
    
    
def create_add_note(vert,img,mp3):
    def add(event):
        c.create_image(0+a,vert,image=img) #
        plus()
        play_note(mp3)
        Mylist.append(mp3)
    return add
 
def bu(event):
    root.destroy()

def play(event):
    for play_note1 in list( Mylist):     
        
        play_note(play_note1)
  
c = Canvas(width=500,height=300,bg="white",cursor="pencil")
c.pack()
for y in range(50,150,20):
    c.create_line(0, y, 500, y, width=2,fill="black")

pilImage = Image.open("notaall.png")
DO= ImageTk.PhotoImage(pilImage)
 
pillImageRe = Image.open('notaall.png')
RE = ImageTk.PhotoImage(pillImageRe)
 
scr = Scrollbar(root)
scr.config(command = c.xview,orient = HORIZONTAL )
scr.pack() 
 
but = Button(root,text='Press to destroy window')
but.place(x=0,y=0)
but.bind('<Button-1>',bu)

but2 = Button(root,text = 'Press to replay')
but2.place(x =200,y = 0) 
but2.bind('<Button-1>',play)

root.bind('a',create_add_note(140,DO,'1.mp3'))
root.bind('s',create_add_note(130,RE,'2.mp3'))
          
root.mainloop()

19

Re: Піаніно на python

У мене сьогодні гарний настрій :)

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time

class Note:

    def __init__(self,name,key,height,mp3,image):
        self.name   = name
        self.key    = key
        self.height = height
        self.mp3    = mp3
        self.image  = ImageTk.PhotoImage( Image.open(image) )
        
    def play(self):
        mixer.init()
        mixer.music.load(self.mp3)
        mixer.music.play()
        time.sleep(0.5)
        mixer.music.stop()

    def event_add_note(self,form):
        def add(event):
            form.canvas.create_image(form.current_position,self.height,image=self.image) #
            form.plus()
            self.play()
            form.list.append(mp3)
        return add

class Form:

    def __init__(self):
        self.root             = Tk()
        self.current_position = 10 # колишнє a
        self.list = [] #YAGN deque
        self.canvas = Canvas(width=500,height=300,bg="white",cursor="pencil")
        self.canvas.pack()
        for y in range(50,150,20):
            self.canvas.create_line(0, y, 500, y, width=2,fill="black")

        self.scr = Scrollbar(self.root)
        self.scr.config(command = self.canvas.xview,orient = HORIZONTAL )
        self.scr.pack()

        self.button_close = Button(self.root,text='Press to destroy window')
        self.button_close.place(x = 0,y = 0)
        self.button_close.bind('<Button-1>',self.destroy)
        
        self.button_play = Button(self.root,text = 'Press to replay')
        self.button_play.place(x = 200,y = 0) 
        self.button_play.bind('<Button-1>',self.play)

        notes = [Note("Do","a",140,"1.mp3","notaall.png"),
                 Note("Re","s",130,"2.mp3","notaall.png")
                #тут продовжити; на майбутнє - можна окремо підвантажувати з файла
                ]

        for note in notes:
            self.root.bind(note.key,note.event_add_note(self))

        self.root.mainloop()

    def plus(self):
        self.current_position += 30
        for y in range(50,150,20):
            self.canvas.create_line(0, y, 500+self.current_position, y, width=2,fill="black")

    def destroy(self,event):
        self.root.destroy()

    def play(self,event):
        for note in self.list:
            note.play()

if __name__ == "__main__":
    main_form = Form()
Подякували: ping, ostap34PHP, Alegzander, leofun01, N1ck5

20

Re: Піаніно на python

koala написав:

У мене сьогодні гарний настрій :)

from tkinter import *
from PIL import Image, ImageTk
from pygame import mixer
import time

class Note:

    def __init__(self,name,key,height,mp3,image):
        self.name   = name
        self.key    = key
        self.height = height
        self.mp3    = mp3
        self.image  = ImageTk.PhotoImage( Image.open(image) )
        
    def play(self):
        mixer.init()
        mixer.music.load(self.mp3)
        mixer.music.play()
        time.sleep(0.5)
        mixer.music.stop()

    def event_add_note(self,form):
        def add(event):
            form.canvas.create_image(form.current_position,self.height,image=self.image) #
            form.plus()
            self.play()
            form.list.append(mp3)
        return add

class Form:

    def __init__(self):
        self.root             = Tk()
        self.current_position = 10 # колишнє a
        self.list = [] #YAGN deque
        self.canvas = Canvas(width=500,height=300,bg="white",cursor="pencil")
        self.canvas.pack()
        for y in range(50,150,20):
            self.canvas.create_line(0, y, 500, y, width=2,fill="black")

        self.scr = Scrollbar(self.root)
        self.scr.config(command = self.canvas.xview,orient = HORIZONTAL )
        self.scr.pack()

        self.button_close = Button(self.root,text='Press to destroy window')
        self.button_close.place(x = 0,y = 0)
        self.button_close.bind('<Button-1>',self.destroy)
        
        self.button_play = Button(self.root,text = 'Press to replay')
        self.button_play.place(x = 200,y = 0) 
        self.button_play.bind('<Button-1>',self.play)

        notes = [Note("Do","a",140,"1.mp3","notaall.png"),
                 Note("Re","s",130,"2.mp3","notaall.png")
                #тут продовжити; на майбутнє - можна окремо підвантажувати з файла
                ]

        for note in notes:
            self.root.bind(note.key,note.event_add_note(self))

        self.root.mainloop()

    def plus(self):
        self.current_position += 30
        for y in range(50,150,20):
            self.canvas.create_line(0, y, 500+self.current_position, y, width=2,fill="black")

    def destroy(self,event):
        self.root.destroy()

    def play(self,event):
        for note in self.list:
            note.play()

if __name__ == "__main__":
    main_form = Form()

Вау! Дійсно велике дякую,зараз розпочну вчити класи(а то мої знання в цій темі доволі вузькі) і думаю,що тоді Ваш код буде зрозуміліший