Problem z wywołaniem okna Tkinter

Odpowiedz Nowy wątek
2019-02-08 16:36
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/downloa[...]cb230bbbe5582059d3f3afe0.html

edytowany 2x, ostatnio: Bartek Pieczka, 2019-02-08 16:41

Pozostało 580 znaków

2019-02-09 10:18
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


Linux Mint
Arduino / Python 3.5.2
edytowany 1x, ostatnio: Guaz, 2019-02-09 10:19

Pozostało 580 znaków

2019-02-09 10:52
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.

edytowany 2x, ostatnio: Bartek Pieczka, 2019-02-09 10:55

Pozostało 580 znaków

2019-02-09 10:57
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():

Linux Mint
Arduino / Python 3.5.2

Pozostało 580 znaków

2019-02-09 11:11
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.

edytowany 2x, ostatnio: Bartek Pieczka, 2019-02-09 11:20

Pozostało 580 znaków

2019-02-09 11:45
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/Threa[...]out-blocking-the-gui-mainloop

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


Linux Mint
Arduino / Python 3.5.2
edytowany 1x, ostatnio: Guaz, 2019-02-09 11:46

Pozostało 580 znaków

2019-02-09 13:40
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.

edytowany 1x, ostatnio: Bartek Pieczka, 2019-02-09 15:10

Pozostało 580 znaków

2019-02-09 20:11
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


Prosząc o pomoc w wiadomości prywatnej odbierasz sobie szansę na otrzymanie pomocy od kogoś bardziej kompetentnego :)
edytowany 1x, ostatnio: superdurszlak, 2019-02-09 20:16

Pozostało 580 znaków

2019-02-09 21:24
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)

Pozostało 580 znaków

2019-02-09 21:27
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.


Prosząc o pomoc w wiadomości prywatnej odbierasz sobie szansę na otrzymanie pomocy od kogoś bardziej kompetentnego :)

Pozostało 580 znaków

2019-02-09 22:32
0

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

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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