آموزش ساخت ماشینحساب با Tkinter در پایتون (گامبهگام و خطبهخط)
کتابخانه Tkinter یکی از سادهترین و در عین حال کاربردیترین ابزارها برای ساخت رابطهای گرافیکی در پایتون است. اگرچه بسیاری از افراد آن را برای پروژههای بزرگ استفاده نمیکنند، اما برای یادگیری اصول رابط کاربری، ساخت ابزارهای کوچک و آشنایی با ساختار برنامههای دسکتاپ انتخاب بسیار مناسبی است. در این مقاله قصد داریم قدمبهقدم ساخت یک ماشینحساب کامل را بررسی کنیم؛ برنامهای که شامل دکمههای عدد، عملگرها، ورودی نمایشگر و پردازش عملیات ریاضی است. آموزش از پایه شروع میشود و در هر مرحله با توضیح دقیق کد، برنامه را توسعه میدهیم تا در نهایت یک ماشینحساب کامل داشته باشیم.
مرحله اول: ایمپورت کتابخانه Tkinter
هر برنامه GUI با Tkinter از این نقطه شروع میشود. ابتدا کتابخانه را وارد برنامه میکنیم.
import tkinter as tk
کتابخانه tkinter بهصورت پیشفرض همراه پایتون نصب میشود. با استفاده از دستور بالا آن را با نام مختصر tk وارد برنامه میکنیم تا در ادامه بتوانیم ویجتها و پنجرهها را راحتتر صدا بزنیم.
مرحله دوم: ساخت پنجره اصلی برنامه
در گام بعد یک پنجره خالی ایجاد میکنیم تا بتوانیم داخل آن ورودی، دکمهها و بقیه اجزای ماشینحساب را قرار دهیم.
win = tk.Tk()
win.title('Calculator')
win.geometry('255x255')
در این بخش چند اتفاق مهم میافتد. با فراخوانی tk.Tk یک پنجره اصلی ایجاد میشود که تمام ویجتها داخل همین پنجره قرار میگیرند. سپس با win.title یک عنوان برای پنجره تعیین میکنیم. در نهایت با win.geometry اندازه پنجره مشخص میشود تا ظاهر برنامه از ابتدا منظم باشد. اینجا عدد 255x255 یک اندازه ثابت برای ماشینحساب تعیین میکند.
مرحله سوم: تعریف چیدمان دکمههای ماشینحساب
در این مرحله لیستی از دکمههایی که قرار است روی ماشینحساب ظاهر شوند تعریف میکنیم تا بعداً آنها را بهترتیب در رابط کاربری قرار دهیم.
buttons = [
['7','8','9','/'],
['4','5','6','*'],
['1','2','3','+'],
['0','.','=','-'],
]
این ساختار به ما اجازه میدهد دکمهها را در ردیفهای منظم نمایش دهیم. هر زیرفهرست یک ردیف جدید است. این روش باعث میشود ساخت دکمهها در حلقه تکرار بسیار سادهتر باشد. بهجای نوشتن چندین دکمه با کدهای تکراری، فقط این ساختار را پیمایش میکنیم.
مرحله چهارم: تعریف تابع مدیریت ورودی دکمهها
هر بار کاربر روی یک دکمه کلیک کند باید یک واکنش اتفاق بیفتد. این واکنش را در تابع keyboard تعریف میکنیم.
def keyboard(key):
if key == '=':
try:
result = eval(inp.get())
inp.delete(0, tk.END)
inp.insert(0, result)
except:
inp.delete(0, tk.END)
inp.insert(0, 'Error')
else:
inp.insert(tk.END, key)
این تابع چند وظیفه دارد. اگر نوع دکمه برابر علامت مساوی باشد، یعنی کاربر قصد محاسبه دارد. برای این کار ابتدا مقدار داخل ورودی خوانده میشود، سپس با eval محاسبه میشود. این روش معادل اجرای مستقیم عبارت ریاضی است. در صورت موفقیت، ورودی پاک میشود و نتیجه جدید وارد میشود. اگر خطا رخ دهد، مقدار Error نمایش داده میشود.
اگر دکمهای بهجز مساوی فشار داده شود، مقدار آن به انتهای رشته فعلی در ورودی اضافه میشود. این اتفاق با inp.insert انجام میشود و دقیقا شبیه ماشینحسابهای معمولی رفتار میکند.
مرحله پنجم: ایجاد ورودی نمایشگر ماشینحساب
ورودی اصلی ماشینحساب با ویجت Entry ساخته میشود.
inp = tk.Entry(win, relief='groove', font=('Fira Code', 20))
inp.pack()
این ورودی همان بخشی است که کاربر مقدار را در آن مشاهده میکند. در اینجا فونت بزرگ انتخاب شده تا خوانایی بهتر باشد. بهکمک pack این ورودی در بالای پنجره قرار میگیرد. پارامتر relief ظاهر فیزیکی کادر را مشخص میکند که در اینجا حالت گروف ظاهر کلاسیکتری به نمایشگر میدهد.
مرحله ششم: ساخت فریمها و دکمهها
در این بخش مهمترین قسمت برنامه یعنی ساخت دکمهها و قرار دادن آنها در چیدمان مناسب انجام میشود.
for row in buttons:
fr = tk.Frame(win)
for btn in row:
if btn in ['/','+','-','=','*']:
back = '#B0ED11'
else:
back = '#1DE1BF'
b = tk.Button(
fr,
text=btn,
width=9, height=3,
font=('Fira Code bold',8),
bg=back,
command=lambda key=btn:keyboard(key))
b.pack(side='left')
fr.pack(fill='both')
در این مرحله برای هر ردیف از دکمهها یک فریم جدا ساخته میشود تا دکمهها کنار هم در یک ردیف قرار بگیرند. سپس هر دکمه بر اساس اینکه عدد باشد یا عملگر، رنگ متفاوتی دریافت میکند. این کار با یک شرط ساده انجام شده تا ظاهر برنامه جذابتر شود.
هر دکمه یک متن دارد که همان کاراکتر نوشته شده در فهرست است. اندازه دکمهها برابر width و height تعیین میشود. مهمترین بخش این ویجت، قسمت command است که با استفاده از یک lambda دکمه را به تابع keyboard متصل میکند. این روش اجازه میدهد هر دکمه مقدار مخصوص خودش را به تابع ارسال کند.
مرحله هفتم: اجرای چرخه اصلی برنامه
در پایان لازم است برنامه وارد حلقه اصلی شود تا پنجره نمایش داده شود و به رویدادهای کاربر واکنش نشان دهد.
win.mainloop()
این خط قلب تپنده برنامههای Tkinter است. بدون آن هیچ پنجرهای نمایش داده نمیشود و کاربر نمیتواند با برنامه تعامل داشته باشد.
کد کامل ماشینحساب با Tkinter
در پایان تمام بخشها را کنار هم قرار میدهیم تا کد نهایی برنامه را داشته باشیم.
import tkinter as tk
win = tk.Tk()
win.title('Calculator')
win.geometry('255x255')
buttons = [
['7','8','9','/'],
['4','5','6','*'],
['1','2','3','+'],
['0','.','=','-'],
]
def keyboard(key):
if key == '=':
try:
result = eval(inp.get())
inp.delete(0, tk.END)
inp.insert(0, result)
except:
inp.delete(0, tk.END)
inp.insert(0, 'Error')
else:
inp.insert(tk.END, key)
inp = tk.Entry(win, relief='groove', font=('Fira Code', 20))
inp.pack()
for row in buttons:
fr = tk.Frame(win)
for btn in row:
if btn in ['/','+','-','=','*']:
back = '#B0ED11'
else:
back = '#1DE1BF'
b = tk.Button(
fr,
text=btn,
width=9, height=3,
font=('Fira Code bold',8),
bg=back,
command=lambda key=btn:keyboard(key))
b.pack(side='left')
fr.pack(fill='both')
win.mainloop()
سخن پایانی
ساخت ماشینحساب با Tkinter یک تمرین عالی برای درک ویجتها، چیدمانها، رویدادها و چرخه اصلی برنامههای دسکتاپ در پایتون است. این پروژه به شما کمک میکند ارتباط بین رابط کاربری و منطق برنامه را بهتر بشناسید. از همین ساختار میتوان برای ساخت ابزارهای پیشرفتهتر مثل دفترچه یادداشت، تبدیلکننده واحد یا اپلیکیشنهای داخلی سازمانی استفاده کرد. امیدوارم این آموزش در آی کد آکادمی به تمام کسانی که علاقه به یادگیری برنامه نویسی و یادگیری پایتون دارند، کمک کرده باشد.