Sytuacja kobiet w IT w 2024 roku
19.11.20214 min
Costas Andreou

Costas AndreouDelivery Lead / VP, Risk ITMizuho International

Szybkie tworzenie UI w Pythonie

Sprawdź, jak stworzyć UI w Pythonie w przypadku, gdy z Twojego produktu korzystać będą m.in. osoby nietechniczne.

Szybkie tworzenie UI w Pythonie

Największą zaletą Pythona jest łatwość użycia i obfitość bibliotek do praktycznie wszystkich zastosowań. Kilka linijek Pythona i masz prawie wszystko. Raczej nie musisz myśleć o ładnym UI, o ile Twoje skrypty są do użytku osobistego albo są przeznaczone dla osób technicznych.

Czasami jednak korzystać z nich będą osoby, które nie są wystarczająco techniczne. Chciałyby używać Twoich wspaniałych skryptów, ale raczej nie będą tego robić, jeżeli będzie to wymagać interakcji z kodem. W tym przypadku wystawienie komendy wiersza poleceń może nie wystarczyć. Przydałoby się UI. Oczywiście tu pojawia się debata - klient desktopowy czy UI webowe, ale na potrzeby tego posta skupię się tylko i wyłącznie na Pythonie.

Biblioteki Pythona do tworzenia UI

W zasadzie mamy trzy duże biblioteki do obsługi UI w Pythonie: Tkinter, wxPython i PyQT. Gdy zapoznawałem się z nimi wszystkimi, uświadomiłem sobie, że używanie ich to zaprzeczenie tego, co lubię w Pythonie. Ogólnie biblioteki Pythona dobrze radzą sobie z tworzeniem abstrakcji z bardzo technicznymi szczegółami. Jeżeli chciałbym pochylać się mocno nad OOP, to pewnie załadowałbym sobie Javę albo .NET.

Ku mojemu zadowoleniu, natknąłem się na czwartą opcję, która bardziej pasowała do tego, co lubię. W końcu wybrałem właśnie tę opcję do tworzenia mojego UI, a biblioteka ta nazywa się PySimpleGUI. Co ciekawe, używa ona trzech wymienionych wcześniej bibliotek, ale tworzy nad nimi abstrakcje, które ukrywają dużo technicznych szczegółów.

Zobaczmy więc, co oferuje ta biblioteka, rozwiązując przy okazji rzeczywisty problem.

Sprawdzenie, że dwa pliki są identyczne

Załóżmy, że potrzebujemy wgrać dwa pliki i wybrać funkcję skrótu, która pozwoli nam porównać te dwa pliki. Tego typu problem wystąpił w moim artykule o sposobach na porównanie danych w Pythonie.

UI

By zbudować UI, możemy użyć takiego kodu:

import PySimpleGUI as sg
layout = [
    [sg.Text('File 1'), sg.InputText(), sg.FileBrowse(),
     sg.Checkbox('MD5'), sg.Checkbox('SHA1')
     ],
    [sg.Text('File 2'), sg.InputText(), sg.FileBrowse(),
     sg.Checkbox('SHA256')
     ],
    [sg.Output(size=(88, 20))],
    [sg.Submit(), sg.Cancel()]
]
window = sg.Window('File Compare', layout)
while True:                             # The Event Loop
    event, values = window.read()
    # print(event, values) #debug
    if event in (None, 'Exit', 'Cancel'):
        break


Czego rezultatem jest:

Podłączenie logiki

Po zrobieniu UI można łatwo połączyć je z resztą kodu. Po prostu musimy monitorować, co wprowadził użytkownik i na to zareagować. Można to zrobić za pomocą takiego kodu:

import PySimpleGUI as sg
import re
import hashlib
def hash(fname, algo):
    if algo == 'MD5':
        hash = hashlib.md5()
    elif algo == 'SHA1':
        hash = hashlib.sha1()
    elif algo == 'SHA256':
        hash = hashlib.sha256()
    with open(fname) as handle: #opening the file one line at a time for memory considerations
        for line in handle:
            hash.update(line.encode(encoding = 'utf-8'))
    return(hash.hexdigest())
layout = [
    [sg.Text('File 1'), sg.InputText(), sg.FileBrowse(),
     sg.Checkbox('MD5'), sg.Checkbox('SHA1')
     ],
    [sg.Text('File 2'), sg.InputText(), sg.FileBrowse(),
     sg.Checkbox('SHA256')
     ],
    [sg.Output(size=(88, 20))],
    [sg.Submit(), sg.Cancel()]
]
window = sg.Window('File Compare', layout)
while True:                             # The Event Loop
    event, values = window.read()
    # print(event, values) #debug
    if event in (None, 'Exit', 'Cancel'):
        break
    if event == 'Submit':
        file1 = file2 = isitago = None
        # print(values[0],values[3])
        if values[0] and values[3]:
            file1 = re.findall('.+:\/.+\.+.', values[0])
            file2 = re.findall('.+:\/.+\.+.', values[3])
            isitago = 1
            if not file1 and file1 is not None:
                print('Error: File 1 path not valid.')
                isitago = 0
            elif not file2 and file2 is not None:
                print('Error: File 2 path not valid.')
                isitago = 0
            elif values[1] is not True and values[2] is not True and values[4] is not True:
                print('Error: Choose at least one type of Encryption Algorithm')
            elif isitago == 1:
                print('Info: Filepaths correctly defined.')
                algos = [] #algos to compare
                if values[1] == True: algos.append('MD5')
                if values[2] == True: algos.append('SHA1')
                if values[4] == True: algos.append('SHA256')
                filepaths = [] #files
                filepaths.append(values[0])
                filepaths.append(values[3])
                print('Info: File Comparison using:', algos)
                for algo in algos:
                    print(algo, ':')
                    print(filepaths[0], ':', hash(filepaths[0], algo))
                    print(filepaths[1], ':', hash(filepaths[1], algo))
                    if hash(filepaths[0],algo) == hash(filepaths[1],algo):
                        print('Files match for ', algo)
                    else:
                        print('Files do NOT match for ', algo)
        else:
            print('Please choose 2 files.')
window.close()


Co da nam taki rezultat:

Podsumowanie

Oczywiście nie jest to zbyt piękne UI, ale ta biblioteka pozwala nam szybko stworzyć proste UI dla programu w Pythonie, by łatwo je było użyć innym osobom. Co ważniejsze, kod, który jest do tego wymagany, jest prosty i czytelny. Nadal trzeba uruchomić kod, by wyświetlić UI, co może uczynić dzielenie się programem nieco trudniejszym. Możesz jednak użyć czegoś w stylu PyInstaller, który zamieni skrypt Pythona w plik .exe, który będzie można po prostu kliknąć i odpalić.



Oryginał tekstu w języku angielskim przeczytasz tutaj

<p>Loading...</p>