Python Tkinter, wczytywanie ścieżki z widgetu entry do funkcji.

Odpowiedz Nowy wątek
2019-07-04 10:38
0

Cześć, jak już niektórzy zauważyli, nie umiem programować :(

Mam kłopot. W pracy napisałem sobie prosty programik który sprawdza czy jakiś plik ma któryś z boków większy niż 32k pikseli. Pików są tysiące a w zasadzie to dziesiątki tysięcy.

Stworzyłem coś takiego :

from PIL import Image
import glob
image_list = {}

for filename in glob.iglob('C:\karton nr 101*/*.jpg'):
    Image.MAX_IMAGE_PIXELS = 1000000000
    im = Image.open(filename)
    if im.size > (32393, 32000) :
        image_list[str(filename)] = str(im.size)

print(image_list)
for key, value in image_list.items():
    print(key + "\t" + value)```

Generalnie super, bo działa.. Ale ścieżkę trzeba podać ręcznie w kodzie, więc jako że z programu w sumie pewnie kilka osób chciałby by korzystać u mnie to postanowiłem zmierzyć się z tematem i napisać program z GUI który będzie wczytywał ścieżkę i podawał ją do funkcji którą przedstawiłem powyżej. Brzmi prosto niby..

I teraz tak rozbiłem program na 2 moduły jeden to moduł z podaną wyżej funkcją, którą zmodyfikowałem w ten sposób :


def check_size(path):
    """Dodałem parametr path i użyłem go w miejscu w którym trzeba wprowadzić ścieżkę"""
    image_list = {}
    for filename in glob.iglob(path + '/*.jpg'):  # assuming gif
        Image.MAX_IMAGE_PIXELS = 1000000000
        im = Image.open(filename)
        if im.size > (32393, 32000):
            image_list[str(filename)] = str(im.size)```

Teraz najgorsze tzn moduł w którym staram się stworzyć okno wprowadzania ścieżki i wywołać funkcje:

import tkinter as tk
from check import check_size

window = tk.Tk()
window.title("be znaczenia")

text = tk.StringVar()
label = tk.Label(window, textvariable=text, padx=200, pady=20)
label.pack()  #
description = tk.Label(window, text="Podaj ścieżkę:").place(x=20, y=10)
name = tk.Entry(window, width=40)
name.place(x=100, y=10)
path=name.get()

button = tk.Button(window, text="Szukaj!", command=check_size(path))
button.pack()

tk.mainloop()```

Problem jest taki, że nie mam zielonego pojęcia jak do path wprowadzić wartość z widgetu entry. Tak na prawdę, to nawet nie wiem czy wartość, która zostanie wprowadzona z entry do path, będzie działać tak jak sobie wymyśliłem. Tzn czy to będzie zwykły ciąg znaków, który można do siebie dodać.

Ktoś coś? Pomocy? Jeśli ktoś wie jak to zrobić prosiłbym o wytłumaczenie, ewentualnie wskazanie źródła w którym jest to dość jasno wytłumaczone.

Z góry dziękuje i mam nadzieję, że nie proszę o za dużo;)

edytowany 1x, ostatnio: NieUmiemProgramować, 2019-07-04 10:46

Pozostało 580 znaków

2019-07-04 13:51

Przejęcie wartości z pola Entry odbywa się za pomocą metody .get() i textvariable StringVar().

Dodatkowo inicjalizując command w ten sposób, niestety wywołujesz funkcję w momencie w którym twój program 'buduje gui' zamiast zrobić to po przyciśnięciu buttona, do tego trzeba wykorzystać funkcje anonimowe. Osobiście zrobiłbym to tak:

test_var = StringVar()
name = tk.Entry(window, textvariable=test_var, width=40)
name.place(x=100, y=10)

button = tk.Button(window, text="Szukaj!", command=lambda path=test_var.get(): check_size(path))

Wtedy command przyjmie funkcje do wywołania, która pobierze wartość z test_var gdy zostanie wywołana.
Inna metoda to stworzyć funkcję z tzw. domknięciem ('closure' znajdziesz po angielsku), ale to jest 'krótszy' sposób załatwienia tego.
Dłuższy bardziej poprawny używający closure:

def tk_check_size(str_var):
    def check_size():
        path = str_var.get()
        """Dodałem parametr path i użyłem go w miejscu w którym trzeba wprowadzić ścieżkę"""
        image_list = {}
        for filename in glob.iglob(path + '/*.jpg'):  # assuming gif
            Image.MAX_IMAGE_PIXELS = 1000000000
            im = Image.open(filename)
            if im.size > (32393, 32000):
                image_list[str(filename)] = str(im.size)
    return check_size

test_var = StringVar()
name = tk.Entry(window, textvariable=test_var, width=40)
name.place(x=100, y=10)

button = tk.Button(window, text="Szukaj!", command=tk_check_size(test_var))

Zaś co do pobierania ścieżki, wydaje mi się że w tkinterze była wbudowana metoda która pozwalała wybrać po prostu plik z dysku, tworzyła okno i pozwalała wybrać plik, przekazując jego ścieżkę :P. Ale musiałbyś poszukać, bo w sumie nie tego dotyczyło pytanie :)

Za walidację ścieżki może odpowiadać na przykład pathlib który też przy okazji zajmie się tym niezależnie czy program zostanie uruchomiony na windzie czy linuxie.


Linux Mint
Arduino / Python 3.5.2
edytowany 6x, ostatnio: Guaz, 2019-07-05 10:05
Generalnie to kod przy próbie uruchomienia "TypeError: check_size() missing 1 required positional argument: 'path'" zgłasza taki błąd. I generalnie to nie wiem jak przekazać ten argument tak aby było ok. - NieUmiemProgramować 2019-07-04 16:29
Mój błąd, poprawiając czyjś kod niestety zdarza mi się zostawić taki kwiatek gdy tego nie odpalę, jeśli poszedłeś za drugim przykładem (tym w którym zmienia się funkcję na domknięcie) to usuń path z argumentów, edytowałem post poprawiając :). Bo patrząc po błędzie, to pewnie będzie ten drugi przykład :). (Oczywiście tu jest tylko edycja pewnych fragmentów, reszta programu po twojemu powinna działać (nie mówię że jakoś super napisane, ale wystarczająco by działać ;>) - Guaz 2019-07-05 10:05
Super! wszystko działa, serio bardzo mi pomogłeś. Dzięki jeszcze raz! - NieUmiemProgramować 2019-07-05 13:01

Pozostało 580 znaków

2019-07-04 15:04
0

Dziękuje bardzo za wyczerpującą wypowiedź. Co do wybierania ścieżki to widziałem, że można za pomocą wbudowanej metody wybrać plik z dysku, ale tutaj sprawa jest taka że ścieżka jest tylko tak na prawdę potrzebna do dysku. Bo dalej jest pierdylion folderów z nazwami dokumentów itd. Więc chce wkleić "C:\karton nr 101****" chyba że jest prostszy sposób na przeszukiwanie folderów i podfolderów.

Nie ukrywam, że trochę tego nie rozumiem. Tzn domyślałem się, że wywołuje tą funkcje albo za wcześnie albo bez sensu. Niby próbuje się uczyć od miesiąca nawet może 2, ale jak w grę zaczyna wchodzić coś w stylu tkinter'a czy pygame( był książce z której się uczyłem ) to się gubię. Staram się jakoś ogarniać temat, ale no nie zawsze wychodzi mi zrozumienie wszystkiego tak aby samodzielnie móc pisać programy. Mam nadzieję, że z czasem będzie mi trochę łatwiej przychodzić zrozumienie jak coś działa.

No nic poczytam o closure i spróbuje ogarnąć temat. Jeszcze raz dziękuje za pomoc.

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