Problem z wywołaniem okna Tkinter

0

Drodzy,
jest kod zawierający klasę Okno(), wewnątrz której (w metodzie ScrolledText) powinien wykonywać się program.
Czy konstrukcja, odwoływania, zagnieżdżenia, typu:

class okno():

     def operacja(init, txt):
            (...)
	
            def nazwa_notki(n):

            def czestotliwosc_na_numer(f):

            def numer_na_czestotliwosc(n)

            def notka_do_fftbin(n):
            (...)

            print (...)
   
            while (...)
     
     window1.mainloop()  

Mogą być? Jeżeli wszystko się kompiluje, to ciężko mi stwierdzić, gdzie jest problem, że to nie jest wywoływane.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
from tkinter import scrolledtext
from tkinter import *
from PIL import ImageTk, Image

class okno():

	window1 = Tk()
	window1.title('Tuner Gitarowy')
	window1.geometry('1380x855')

	img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
	window1 = Label(window1, background='NavajoWhite3', image=img)
	window1.pack(side='right', fill='both', expand='yes')

	txt = scrolledtext.ScrolledText(window1, width=60, height=53)
	txt.grid(column=0, row=1)

	def operacja(init, txt):
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT

		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		print('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')


		# otrzymywane dane w czasie:
		while stream.is_active(txt):
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			txt.insert(INSERT, 'Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))

	window1.mainloop()

Udostępniam paczkę z kodem, chodzi o "Guitar.py", python, jakiego używam do kompilacji jest w wersji 2.7
https://megawrzuta.pl/download/290e41fecb230bbbe5582059d3f3afe0.html

1

Wszystko co masz po jednym wcięciu, jak na przykład:

    window1.mainloop()

Przenieś do metody:

    def __init__(self):
        self.window1 = Tk()
        # Reszta kodu w tym wcięciu
        self.window1.mainloop()

I pamiętaj by poprzedzić parametrem self. to co ma być widoczne w metodach tej klasy

0

Guaz, dziękuję za odpowiedź.
Czy dobrze zrozumiałem?

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
from tkinter import scrolledtext
from tkinter import *
from PIL import ImageTk, Image

class okno():

	def __init__(self):
		self.window1 = Tk()

		self.window1.title('Tuner Gitarowy')
		self.window1.geometry('1380x855')

		self.img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		self.window1 = Label(self.window1, background='NavajoWhite3', image=img)
		self.window1.pack(side='right', fill='both', expand='yes')

		self.txt = scrolledtext.ScrolledText(self.window1, width=60, height=53)
		self.txt.grid(column=0, row=1)
		self.window1.mainloop()

	def operacja():
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT

		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		print('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')

		# otrzymywane dane w czasie:
		while stream.is_active():
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			print('Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))

Bo jeżeli jest dobrze, to zastanawiam się, czy w
def operacja () - nie powinno być jakiegoś odniesienia + w:
while stream.is_active():

class okno():

	def __init__(self):
        (kod)

       def operacja():
       (kod)

		def nazwa_notki(n):

		def czestotliwosc_na_numer(f):

		def numer_na_czestotliwosc(n):

		def notka_do_fftbin(n):

		while stream.is_active():
		(kod)

Program kompiluje, lecz dalej nie wyświetla okna.

1

Zdecydowanie nie.

Nie możesz wszystkiego domykać (Closure). Zwłaszcza w metodzie __init__.

Teraz pozostaje ci utworzyć obiekt i wywołać twoją metodę:
np.

o = Okno()
o.operacja()

No i w definicji operacja brakuje ci parametru self:

def operacja(self):

Chyba że nie chcesz się odwoływać do okna, to możesz zrobić z tego statyczną metodę, tylko wtedy traci to sens używania OOP (Object Oriented Programing), które i tak nie wiem za szczególnie po co tu używasz i do czego w ogóle ma służyć twoja klasa.
Ale tak i tak podam przykład:

@staticmethod
def operacja():
0
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
from tkinter import scrolledtext
from tkinter import *
from PIL import ImageTk, Image

class Okno(object):

	def __init__(self):
		window1 = Tk()

		window1.title('Tuner Gitarowy')
		window1.geometry('1380x855')

		img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(window1, background='NavajoWhite3', image=img)
		window1.pack(side='right', fill='both', expand='yes')

		txt = scrolledtext.ScrolledText(window1, width=60, height=53)
		txt.grid(column=0, row=1)
		window1.mainloop()

	def operacja(self):
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT

		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		print('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')

		# otrzymywane dane w czasie:
		while stream.is_active():
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			print('Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))


o = Okno()
o.operacja()

Pokazuje okno, niestety puste:
screenshot-20190209111027.png

I po zamknięciu okna, w konsoli, w pętli działa tuner:
screenshot-20190209111132.png

Jednego niestety nie zrozumiałem.
Guaz - napisałeś, żebym poprzedził parametrem self, to co ma być widoczne w metodach tej klasy.
Czyli główne okno (window1) + metodę ScrolledText (txt), tak?
Bo gdy tak robię, to program się nie kompiluje.

1

A wszędzie gdzie używasz tych zmiennych, dopisujesz self?
np. Tu:

        self.window1 = Label(self.window1, background='NavajoWhite3', image=img)

Dla img.

A jeśli twoja metoda ma działać w mainloopie Tk. Jest na to kilka sposobów. Async, Threating, albo wywołanie wewnątrz pętli tkintera:

    def __init__(self):
        self.window1 = Tk()

        self.window1.title('Tuner Gitarowy')
        self.window1.geometry('1380x855')

        self.img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
        self.window1 = Label(self.window1, background='NavajoWhite3', image=self.img)
        self.window1.pack(side='right', fill='both', expand='yes')

        self.txt = scrolledtext.ScrolledText(self.window1, width=60, height=53)
        self.txt.grid(column=0, row=1)

        self.operacja() #~ Tylko w ten sposób to nie będzie działać, to symboliczne przedstawienie.
        self.window1.mainloop()

To jednak wymaga od ciebie aby tej operacji nie wywoływać wewnątrz while ponieważ na czas trwania while twoje okno się zawiesi bez mainloopa.

Ogólnie teraz już chyba rozumiem co chcesz zrobić, i powinieneś to całkowicie przebudować:
https://python-forum.io/Thread-Tkinter-How-to-update-the-gui-in-a-loop-without-blocking-the-gui-mainloop

Ten wątek wyjaśnia dlaczego masz w ogóle błędne założenie w zaprojektowaniu tej klasy.

0

Czy ten kod Wam się kompiluje?

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
import tkinter
from PIL import ImageTk, Image
from tkinter import *
from tkinter import scrolledtext

UPDATE_RATE = 1000

class Okno(tkinter.Frame):


	def __init__(self, master):
		tkinter.Frame.__init__(self, master)

		self.operacja()


	def operacja(self):
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT


		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		print('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')


		# otrzymywane dane w czasie:
		while stream.is_active():
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			print('Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))

		img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(window1, background='NavajoWhite3', image=img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(window1, width=60, height=53)
		txt.grid(column=0, row=1)


window1 = tkinter.Tk()
window1.title('Tuner Gitarowy')
window1.geometry('1380x855')
window1.operacja()

o = Okno(window1)
window1.mainloop()
		img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(window1, background='NavajoWhite3', image=img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(window1, width=60, height=53)
		txt.grid(column=0, row=1)

Nie wiem, gdzie umieścić ten fragment; Pod metodą def init, czy już w wywołaniu tej klasy.
Wgl. Te wywołanie dziwnie tu wygląda, jakoś mi to nie leży. Nie potrafię dobrze odnieść mojego kodu do przykładu Panie Guaz.

Błąd podczas kompilacji:
screenshot-20190209134003.png
A chyba wszystko jest dobrze zimportowane.
Hmm, dziwne.
Próbowałem:
import tkinter as tk
Nie trybi.

1

Gdy importujesz w ten sposób:

from tkinter import *

To odwołanie do zawartości modułu poprzez jego nazwę nie zadziała:

frame = tkinter.Frame() 

Używając from moduł import coś odwołuj się bezpośrednio do importowanej zawartości:

frame = Frame()

Poza tym sugeruję nie używać słowa kompilacja w kontekście uruchamiania kodu napisanego w Pythonie interpreterem Pythona (obstawiam, że pod spodem Twój config Guitar z PyCharm odpala po prostu python skrypt.py). To jest mylące. Parę dni temu zajrzałem w jeden z Twoich wątków święcie przekonany (sądząc po temacie), że masz jakiś problem objawiający się podczas faktycznej kompilacji Pythona (co zresztą jest możliwe, i może faktycznie powodować różne dziwne problemy) :P

0

Próbowałem:
from tkinter import Frame
from tkinter import frame
from _tkinter import Frame
from _tkinter import frame

Nie chce pobrać paczek, nic nie działa.
Python 2.7.15, programu pycharm (najnowsza wersja)

1
Bartek Pieczka napisał(a):

Próbowałem:
from tkinter import Frame
from tkinter import frame
from _tkinter import Frame
from _tkinter import frame

Nie chce pobrać paczek, nic nie działa.
Python 2.7.15, programu pycharm (najnowsza wersja)

A spróbowałeś tego?

 from Tkinter import Frame

W Pythonie 2.7 nazwa modułu Tkinter zaczyna się od wielkiej litery. Python jest case-sensitive.

0

Wcześniejsze importy zaczynały się z małej litery i działało.
O taki problemik:
screenshot-20190209223156.png

1

Wywal w końcu to odwołanie do modułu tkinter. Jak nie wierzysz, to otwórz sobie konsolę Pythona i sam sprawdź. Poniżej masz screeny na dowód.

Python 3 -> moduł nazywa się tkinter, nie rozpoznaje Tkinter
screenshot-20190210002332.png

Python 2 -> moduł nazywa się Tkinter, nie rozpoznaje tkinter
screenshot-20190210002347.png

0

Superdurszlak, przepraszam Cię, ale próbuję robić ten kod metodą prób i błędów już od 3 tygodni.
Kompiluje się bez błędów, nie wyświetla okna.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
from PIL import ImageTk, Image
from tkinter import *
from tkinter import scrolledtext

UPDATE_RATE = 1000

class Okno(object):


	def __init__(self, master):

		window1 = Tk()
		window1.title('Tuner Gitarowy')
		window1.geometry('1380x855')

		img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(window1, background='NavajoWhite3', image=img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(window1, width=60, height=53)
		txt.grid(column=0, row=1)

		self.operacja()
		window1.mainloop()

	def operacja(self):
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT


		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		print('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')


		# otrzymywane dane w czasie:
		while stream.is_active():
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			print('Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))






app = Okno
app.__init__
app.operacja
0

screenshot-20190210013851.png
Wersja: 2.7

1
app = Okno
app.__init__
app.operacja

Jak chcesz stworzyć obiekt Okno, to musisz wywołać konstruktor i metodę, którą chcesz wywołać. Tutaj nie wywołujesz nic.

Btw po co init przyjmuje argument master, skoro tworzysz w nim okno aplikacji od zera tzn od Tk()?

Może pora porzucić metodę prób i błędów na rzecz metody "czytam dokumentację lub przynajmniej tutoriale żeby robić rzeczy ze zrozumieniem"? :)

0
superdurszlak napisał(a):
app = Okno
app.__init__
app.operacja

Jak chcesz stworzyć obiekt Okno, to musisz wywołać konstruktor i metodę, którą chcesz wywołać. Tutaj nie wywołujesz nic.

Btw po co init przyjmuje argument master, skoro tworzysz w nim okno aplikacji od zera tzn od Tk()?

Może pora porzucić metodę prób i błędów na rzecz metody "czytam dokumentację lub przynajmniej tutoriale żeby robić rzeczy ze zrozumieniem"? :)

Moja pomyłka, przepraszam. Myślałem, że wywołuję.
master - usunięty.

Ogólnie - podchodząc do problemu wywołania obliczeń w pętli, wewnątrz okna, nie spodziewałem się, że będzie to takie trudne i problematyczne.
Jak już wspomniałem - robiłem na wiele sposobów, m. in. w oparciu o książkę: "Zanurkuj w Pythonie", a także: "Python, wprowadzenie, wydanie IV".

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
from tkinter import scrolledtext, Label, Tk
from PIL import ImageTk, Image

UPDATE_RATE = 1000

class Okno(object):


	def okieneczko(self):

		window1 = Tk()
		window1.title('Tuner Gitarowy')
		window1.geometry('1380x855')

		img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(window1, background='NavajoWhite3', image=img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(window1, width=60, height=53)
		txt.grid(column=0, row=1)

		self.operacja()
		window1.mainloop()

	def operacja(self):
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT


		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		print('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')


		# otrzymywane dane w czasie:
		while stream.is_active():
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			print('Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))


app = Okno()
app.okieneczko()
# app.operacja()

W:

	def okieneczko(self):

		window1 = Tk()
		window1.title('Tuner Gitarowy')
		window1.geometry('1380x855')

		img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(window1, background='NavajoWhite3', image=img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(window1, width=60, height=53)
		txt.grid(column=0, row=1)

		self.operacja()
		window1.mainloop()

Ciekawa rzecz.
Jeżeli w metodzie def okieneczko nic nie zrobię z self.operacja(), nie wyprintuje okna tkinter - program bedzie działał.
Gdy zakomentuję:

  • self.operacja(), okno się włączy. Po wyłączeniu nic się nie stanie.
0
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
import tkinter
from tkinter import scrolledtext, Label, Tk
from PIL import ImageTk, Image

UPDATE_RATE = 1000

class Okno(tkinter.Frame):


	def __init__(self, master):
		tkinter.Frame.__init__(self, master)

		self.window1 = Tk()
		self.img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(self.window1, background='NavajoWhite3', image=self.img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(self.window1, width=60, height=53)
		txt.grid(column=0, row=1)
		self.yy()
		self.stream.is_active()
		self.xx()

		self.window1.mainloop()

	def operacja(self):
		FSAMP = 22050  # czestotliwosc probkowania w Hz
		ROZMIAR_PROB = 2048  # ilosc probek
		KLATEK_NA_FFT = 16  # ilosc klatek zajmujacych srednio przez szybka transformate fouriera
		NOTKA_MIN = 40  # E2
		NOTKA_MAX = 64  # E4

		# dla wyswietlenia nazw dzwieku
		NOTACJA = 'E F F# G G# A A# B C C# D D#'.split()

		# nowe dzwieki
		PROBKI_NA_FFT = ROZMIAR_PROB * KLATEK_NA_FFT
		KROK_CZESTOTLIWOSCI = float(FSAMP) / PROBKI_NA_FFT


		def nazwa_notki(n):
			return NOTACJA[n % NOTKA_MIN % len(NOTACJA)] + str(int(n / 12 - 1))

		def czestotliwosc_na_numer(f):
			return 64 + 12 * np.log2(f / 329.63)

		def numer_na_czestotliwosc(n):
			return 329.63 * 2.0 ** ((n - 64) / 12.0)

		# pobranie minumalnego\maksymalnego nr indeksu z szybkiej transformaty fouriera
		def notka_do_fftbin(n):
			return numer_na_czestotliwosc(n) / KROK_CZESTOTLIWOSCI

		imin = max(0, int(np.floor(notka_do_fftbin(NOTKA_MIN - 1))))
		imax = min(PROBKI_NA_FFT, int(np.ceil(notka_do_fftbin(NOTKA_MAX + 1))))

		# Przydzial przestrzeni aby uruchomic szybka transformate fouriera
		buf = np.zeros(PROBKI_NA_FFT, dtype=np.float32)
		numer_klatki = 0

		# inicjalizacja dzwieku
		stream = pyaudio.PyAudio().open(format=pyaudio.paInt16, channels=1, rate=FSAMP, input=True, frames_per_buffer=ROZMIAR_PROB)
		stream.start_stream()

		# tworzenie funkcji Hanninga
		window = 0.5 * (1 - np.cos(np.linspace(0, 2 * np.pi, PROBKI_NA_FFT, False)))

		# wypisanie poczatkowego tekstu
		self.yy = ('pobieranie probek w:', FSAMP, 'Hz z maksymalna rozdzielczoscia', KROK_CZESTOTLIWOSCI, 'Hz')


		# otrzymywane dane w czasie:
		while self.stream.is_active(scrolledtext):
			# przesuwanie bufora i wprowadzenie nowych danych
			buf[:-ROZMIAR_PROB] = buf[ROZMIAR_PROB:]
			buf[-ROZMIAR_PROB:] = np.fromstring(stream.read(ROZMIAR_PROB), np.int16)

			# Uruchom szybka transformate fouriera na okiennym buforze
			fft = np.fft.rfft(buf * window)

			# pobierz czestotliwosc maksymalnej wartosci z zakresu
			czestotliwosc = (np.abs(fft[imin:imax]).argmax() + imin) * KROK_CZESTOTLIWOSCI

			# pobierz numer notatki i najblizsza notatke
			n = czestotliwosc_na_numer(czestotliwosc)
			n0 = int(round(n))

			# dane wyjsciowe konsoli, gdy mamy pelny bufor
			numer_klatki += 1
			self.xx = ('Numer: {:7.2f}     Wysokosc: {:7.2f} Hz     Nota: {:>3s} {:+.2f}'.format(n, czestotliwosc, nazwa_notki(n0), n - n0))


app = tkinter.Tk()
app.title('Tuner Gitarowy')
app.geometry('1380x855')

o = Okno(app)
o.Okno()
o.operacja()

screenshot-20190211132501.png

Co mu nie odpowiada, że:

(linijka 19) window1 = Label(self.window1, background='NavajoWhite3', image=self.img)
(linijka 100) o = Okno(app)

Kurczę, no czytałem dokumentację i zrozumiałem to tak, że init powinno się wywoływać bezpośrednio po utworzeniu klasy. Mając przypisanego selfa (odwołuje się do samej siebie).
Opierając się o kod Guaza, wydawało mi się, że jest to poprawnie opisane.

1
o = Okno(app)
o.Okno()

Nope, nope, nope.

Już przy tworzeniu obiektu:

o = Okno(app)

pod spodem wywołuje się metoda __init__

0

Ok, to już jest chyba dobrze.

app = tkinter.Tk()
app.title('Tuner Gitarowy')
app.geometry('1380x855')

o = Okno(app)
app.mainloop()

Linijka 19sta dalej mu nie pasuje:

	def __init__(self, master):
		tkinter.Frame.__init__(self, master)

		self.window1 = Tk()
		self.img = ImageTk.PhotoImage(Image.open('z_gitara.png'))
		window1 = Label(self.window1, background='NavajoWhite3', image=self.img)
		window1.pack(side='right', fill='both', expand='yes')
		txt = scrolledtext.ScrolledText(self.window1, width=60, height=53)
		txt.grid(column=0, row=1)
		self.yy()
		self.stream.is_active()
		self.xx()

Tak wygląda ten init.
Krzaczy mu przy wywołaniu img:

window1 = Label(self.window1, background='NavajoWhite3', image=self.img)
1
Bartek Pieczka napisał(a):

Tak wygląda ten init.
Krzaczy mu przy wywołaniu img:

window1 = Label(self.window1, background='NavajoWhite3', image=self.img)

Bo tworzysz luźny obiekt window1, a próbujesz odwołać się do niego jak do pola: self.window1

0

screenshot-20190211145740.png

self.window1 = Label(self.window1, background='NavajoWhite3', image=self.img)

Wiem, że lamię, ale ta korekta nic nie dała.

1
superdurszlak napisał(a):
Bartek Pieczka napisał(a):

Tak wygląda ten init.
Krzaczy mu przy wywołaniu img:

window1 = Label(self.window1, background='NavajoWhite3', image=self.img)

Bo tworzysz luźny obiekt window1, a próbujesz odwołać się do niego jak do pola: self.window1

Nie w tym problem, spójrz dwie linie wyżej :)

        self.window1 = Tk()

To już deklarujesz zmienną app.
Teraz usuń te linię którą tu zacytowałem.

Ale to po prostu błąd, jednak nadal nie jest to tym błędem który wyskoczył w interpreterze. Chodzi o obrazek:

Zresztą... Zaimportuj:

from tkinter import *

Wynikowo twój __init__ oraz deklaracja klasy powinna wyglądać tak:

class Okno(Tk.Frame):
    def __init__(self, master):
        super().__init__(self, master)

        self.img = Tk.PhotoImage(file='button_hh.png')
        self.window1 = Label(self, background='NavajoWhite3')
        self.window1.config(image=self.img)
        self.window1.image = self.img #To raczej nie jest potrzebne, ale nie jestem pewny, bo nie pamiętam. Dodaję w razie czego. 
        self.window1.pack(side='right', fill='both', expand='yes')
        self.txt = scrolledtext.ScrolledText(self.window1, width=60, height=53)
        self.txt.grid(column=0, row=1)
        self.yy()
        self.stream.is_active()
        self.xx()

Przy takim wywołaniu:

app = tkinter.Tk()
app.title('Tuner Gitarowy')
app.geometry('1380x855')

o = Okno(app)
app.mainloop()

Mam nadzieję że nigdzie się nie machnąłem, bo przez śledzenie wątku przez tyle wersji, już zacząłem się w tym gubić. Jeśli to nie pomoże, wyślij w załączniku cały plik, poprawię ci go i zaznaczę zmienione fragmenty, dla mojego spokoju ducha :D. I w twoich rękach zostawię czy zrozumiesz dlaczego jedne rzeczy będą tak rozwiązane, a inne inaczej :).

1 użytkowników online, w tym zalogowanych: 0, gości: 1