1

Здравствуйте. Есть такой код, вроде пианино.

`

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()

введите сюда описание изображения

`

Как корректно исправить ошибку?

Raccoon
  • 113
  • 1
    вы хотите хранить последние 8 проигранных нот? Просто в collections.deque(maxlen=8) добавляйте ноты, в каждой функции, которая ноту проигрывает (можно декоратор определить, чтобы не дублировать код). А чтобы проиграть, создайте словарик: имя ноты -> функция, которая проигрывает (используйте этот словарь, чтобы при вызове root.bind(), чтобы избежать дублирования и рассинхронизации). Если это не ясно, спрашивайте. – jfs Aug 06 '17 at 14:04
  • А как правильно объявить словарь? Вот так не работает: ]A = dict([( 'do',do()),('re',re()),('mi',mi()),('fa',fa()),('so',so()),('lu',lu()),('si',si())]) 2) Не совсем понял как в зависимости от данных полученных в collections.deque() проиграются ноты. @jfs
  • – Raccoon Aug 08 '17 at 15:17
  • 1
    dict(do=do, re=re, ..). Помните, что если f это функция, то f() вызывает эту функцию в Питоне (и поэтому равно, тому что эта функция возвращает). – jfs Aug 08 '17 at 15:18
  • Спасибо,понял как нужно правильно объявить список,но как в зависимости от данных полученных в collections.deque() проиграются ноты.@jfs – Raccoon Aug 08 '17 at 15:25
  • 1
    Вы кладёте сами функции в history=deque(maxlen=8). history.append(do) (внутри декоратора это выглядит как history.append(func); func() (добавить в историю, проиграть) — если слово декоратор вам ничего не говорит, спрашивайте). Чтобы проиграть всю историю: for play_note in history: play_note(). – jfs Aug 08 '17 at 15:31
  • Буду очень благодарен если Вы мне еще раз объясните последнее сообщение. И да я не знаю,что такое декоратор. Пробывал ппрочитать(https://pythonworld.ru/osnovy/dekoratory.html) но не особо понял.@jfs – Raccoon Aug 08 '17 at 15:44
  • если хочется с помощью кода музыку создавать, то попробуйте http://sonic-pi.net/ (простой код, достаточно приятных результатов позволяет быстро достигать и можно даже в живую с помощью кода импровизировать) – jfs Aug 08 '17 at 18:25
  • 1
    Стоит упомянуть, что у вас в коде есть и другие проблемы. К примеру: не используйте time.sleep() внутри обработчика событий (используйте root.after()) иначе вы "замораживаете" GUI (Мультизадачность на Python: выполнить две долгие функции одновременно, не блокируя GUI). По мелочи: если вы pygame используете, то у него есть функции, которые позволяют и клавиши отслеживать и рисовать (случайный пример: pygame-piano.py). В целом, как я упомянул, мне нравится подход в Sonic Pi (play sample, sleep, multiple concurrent loops) – jfs Aug 09 '17 at 06:02