ساخت سریع UI در پایتون به زبان ساده

بزرگ‌ترین مزیت پایتون، سهولت استفاده و فراوانی کتابخانه‌ها برای همه کارها است. بدین ترتیب با نوشتن چند خط کد همه کاری می‌توان انجام داد. تا زمانی که اسکریپت‌های پایتون را برای استفاده شخصی می‌نویسید یا مخاطبان هدف شما به قدر کافی فنی هستند، نیاز نیست در مورد «رابط کاربری» (User Interface) یا به اختصار UI نگران باشید. اما برخی اوقات مخاطبان ما اطلاعات فنی چندانی ندارند. آن‌ها به استفاده از اسکریپت‌های پایتون تا زمانی علاقه دارند که مجبور نباشند به یک خط کد نگاه کنند. در این موارد ارائه اسکریپت‌های خط فرمان کار مفیدی محسوب نمی‌شود و باید یک UI برای آن‌ها تدارک ببینیم. با این که برخی از افراد از کلاینت‌های دسکتاپ به جای UI مبتنی بر وب استفاده می‌کنند، اما ما در این مقاله روی ساخت سریع UI در پایتون تمرکز خواهیم داشت.

کتابخانه‌های پایتون برای ساخت UI

اساساً 3 کتابخانه بزرگ UI برای پایتون وجود دارند که Tkinter ،wxPython و PyQT نام دارند. ما در این مقاله هر سه این کتابخانه‌ها را بررسی می‌کنیم، ‌اما چیزی که به دنبالش هستیم در هیچ کدام از این کتابخانه‌ها نیست. کتابخانه‌های پایتون به طور کلی یک روش مناسب برای جداسازی بخش کاملاً فنی برنامه‌های محسوب می‌شوند. با این حال اغلب تمرکز ما در این مقاله روی گزینه چهارم یعنی کتابخانه PySimpleGUI است. این کتابخانه از هر 3 کتابخانه فوق استفاده می‌کند، اما بخش‌های فنی آن‌ها را از دید ما دور نگاه می‌دارد. بدون هیچ گونه توضیح اضافی به بررسی این کتابخانه می‌پردازیم و یک مسئله واقعی را نیز هم‌زمان حل خواهیم کرد.

بررسی یکسان بودن دو فایل

فرض کنید پروژه‌ای داریم که در آن می‌خواهیم داده‌ها را در پایتون با هم مقایسه کنیم. بدین منظور باید دو فایل را بارگذاری کنیم و سپس رمزگذاری مناسب برای استفاده در مقایسه فایل را انتخاب کنیم.

کدنویسی UI

برای ساخت UI می‌توانیم از کد زیر استفاده کنیم:

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

که نتیجه زیر را تولید می‌کند:

بررسی منطق برنامه

اینک که UI آماده است به راحتی می‌توانیم بقیه کد را نیز متصل کنیم. کافی است ورودی‌های کاربر را مورد رصد قرار دهیم و سپس بر همین اساس عمل کنیم. این کار به سادگی با استفاده از کد زیر ممکن است:

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()

با اجرای کد فوق، خروجی زیر حاصل می‌شود:

سخن پایانی

با این که این UI چندان زیبا نیست، اما این کتابخانه به ما امکان می‌دهد که اقدام به ساخت سریع UI در پایتون بکنیم و آن‌ها را با هر کسی که نیاز دارد به اشتراک بگذاریم. نکته جالب‌تر این است که کدی که به این منظور نیاز داریم، کاملاً ساده و خوانا است. ما همچنان با مشکل اجرای کد برای رسیدن به UI مواجه خواهیم بود، که بحث اشتراک‌گذاری را کمی دشوار می‌سازد، اما می‌توانید از چیزی مانند PyInstaller استفاده کنید که اسکریپت پایتون را به یک فایل exe. تبدیل می‌کند و افراد می‌توانند به سادگی با دابل-کلیک اجرا کنند.