Попытка сделать светофор, который меняет цвет в зависимости от звука (громкий звук = красный, нормальный звук = зеленый и т. Д.) - PullRequest
0 голосов
/ 31 января 2019

Я пытался создать приложение Tkinter, которое будет работать как сигнал обратной связи для воспроизводимого звука.так, например, когда в библиотеке становится громко, вы получаете красный свет, но когда он нормальный, то зеленый и т. д.

В основном я создал приложение Tkinter с холстом и сделал 3 круга в прямоугольнике.(стоп-сигнал) также сделал функцию для получения входного сигнала от вашего микрофона, чтобы увидеть, насколько высок или низок звук.

Этот код сделан в отдельном файле для получения входного звука:

def decide_colour():

    def print_sound(indata, outdata, frames,tijd, status):
        global colour
        volume_norm = np.linalg.norm(indata)
        print(volume_norm)
        time.sleep(1)

        #set fill colour
        if volume_norm > 2 and volume_norm <4:
            colour = "yellow"
        elif volume_norm > 4:
            colour = "red"
        else:
            colour = "green"

        print(colour)

    with sd.Stream(callback=print_sound):
        sd.sleep(duration * 1000)


decide_colour()

И это приложение tkinter, которое должно отображать его:

class TrafficLights:

    def __init__(self):

        root = Tk()
        root.title("Stoplicht")
        root.configure(bg='black')
        root.geometry('460x400')

        # Frame voor widgets
        frame = Frame(root)
        frame.grid()

        self.colour = StringVar()

        # canvas voor lichten
        self.canvas = Canvas(root, width=460, height=400, bg="black")
        self.canvas.create_rectangle(190, 10, 310, 350, outline='white', fill='black')
        self.canvas.grid()

        self.oval_red = self.canvas.create_oval(200, 20, 300, 120, fill="white")

        self.oval_yellow = self.canvas.create_oval(200, 130, 300, 230, fill="white")

        self.oval_green = self.canvas.create_oval(200, 240, 300, 340, fill="white")

        # kleurbepaling voor de cirkels
        def change_color(self):

            if colour == 'red':
                self.canvas.itemconfig(self.oval_red, fill="red")
                self.canvas.itemconfig(self.oval_yellow, fill="white")
                self.canvas.itemconfig(self.oval_green, fill="white")
            elif colour == 'yellow':
                self.canvas.itemconfig(self.oval_red, fill="white")
                self.canvas.itemconfig(self.oval_yellow, fill="yellow")
                self.canvas.itemconfig(self.oval_green, fill="white")
            elif colour == 'green':
                self.canvas.itemconfig(self.oval_red, fill="white")
                self.canvas.itemconfig(self.oval_yellow, fill="white")
                self.canvas.itemconfig(self.oval_green, fill="green")

        change_color(self)

        root.after(500, change_color(self))
        #root.after(500, TrafficLights)

        root.mainloop()


while True:
    decide_colour()
    TrafficLights()

Но оно застряло в цикле.а также, избавившись от оператора while, он просто откроет его один раз.Но я хочу, чтобы он продолжал работать, и я хочу, чтобы он менял цвет светофора.Я пытался в течение нескольких дней, в поисках ответов.но я просто сейчас застрял.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Хорошо, это не тот ответ, который я хотел, но, тем не менее, это ответ.

Я собрал коды, и с некоторыми изменениями я пришел к этому.

from tkinter import *
import sounddevice as sd
import numpy as np
import time

duration = 1  #


def decide_colour():
    def print_sound(indata, outdata, frames, tijd, status):
        global colour
        volume_norm = np.linalg.norm(indata)
        time.sleep(1)

        # set fill colour
        if 2 < volume_norm < 4:
            colour = "yellow"
        elif volume_norm > 4:
            colour = "red"
        else:
            colour = "green"

        print(volume_norm, colour)

    with sd.Stream(callback=print_sound):
        sd.sleep(duration * 1000)


class TrafficLights:

    def __init__(self):

        root = Tk()
        root.title("Stoplicht")
        root.configure(bg='black')
        root.geometry('460x400')

        # Frame voor widgets
        frame = Frame(root)
        frame.grid()

        self.colour = StringVar()

        # canvas voor lichten
        self.canvas = Canvas(root, width=460, height=400, bg="black")
        self.canvas.create_rectangle(190, 10, 310, 350, outline='white', fill='black')
        self.canvas.grid()

        self.oval_red = self.canvas.create_oval(200, 20, 300, 120, fill="red")
        self.oval_yellow = self.canvas.create_oval(200, 130, 300, 230, fill="white")
        self.oval_green = self.canvas.create_oval(200, 240, 300, 340, fill="white")

    def create_frame():
        decide_colour()

        if colour == 'red':
            self.canvas.itemconfig(self.oval_red, fill="red")
            self.canvas.itemconfig(self.oval_yellow, fill="white")
            self.canvas.itemconfig(self.oval_green, fill="white")
        elif colour == 'yellow':
            self.canvas.itemconfig(self.oval_red, fill="white")
            self.canvas.itemconfig(self.oval_yellow, fill="yellow")
            self.canvas.itemconfig(self.oval_green, fill="white")
        elif colour == 'green':
            self.canvas.itemconfig(self.oval_red, fill="white")
            self.canvas.itemconfig(self.oval_yellow, fill="white")
            self.canvas.itemconfig(self.oval_green, fill="green")

        create_frame()

        root.update()
        time.sleep(1)
        root.destroy()
        return


while True:
    TrafficLights()

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

0 голосов
/ 01 февраля 2019

Кажется, проблема в организации вашей программы.Эта while петля не нужна.Я сделал простой пример того, как after должен работать.Функция, которая вызывается в цикле after, должна получать необходимые данные из функции decide_colour().В этом примере это будет my_count().

from tkinter import *

class Counter(Frame):

    def __init__(self, master=None):
        self.count = 0
        super().__init__(master)
        self.grid()
        self.__create_widgets()

    def __create_widgets(self):
        self.count_label         = Label(self)
        self.count_label["text"] = str(self.count)
        self.count_label["pady"] = 5
        self.count_label.grid()


    def my_count(self):
        self.count = self.count+1
        self.count_label["text"] = str(self.count)


root = Tk()
counter = Counter(master=root)

#do you app set up here
root.title("Counter")
root.geometry('460x400')

def do_one_iteration():
    counter.my_count()
    root.after(500, do_one_iteration)
do_one_iteration()

counter.mainloop()
...