مستر کد
mrcode.wikibix.ir

آموزش کتابخانه گرافیکی پایتون

نویسنده : نازنین رحمانی | زمان انتشار : 09 اسفند 1399 ساعت 21:04

جهت انجام پروژه های دانشجویی و یا تمرین‌های برنامه نویسی رشته کامپیوتر میتوانید به آی دی تلگرام زیر پیام دهید

@AlirezaSepand



بیشتر افرادی که برای اولین بار قصد ورود به حوزه‌ی برنامه نویسی دارند، تصورشان از برنامه نویسی، ساخت برنامه‌های گرافیکی است؛ در صورتی که برنامه‌های گرافیکی، فقط بخشی از حوزه‌ی برنامه نویسی هستند. پایتون، یک زبان ایده‌آل برای ایجاد برنامه‌های گرافیکی نیست، اما با وجود کتابخانه‌هایی نظیر Tkinter ،kivy و... ، می‌توان برنامه‌های گرافیکی بسیار خوبی با استفاده از پایتون نوشت. ما در این قسمت، کتابخانه‌ی پرکاربرد و محبوب Tkinter پایتون را به شما آموزش می‌دهیم. اگر علاقه‌مند به این مبحث هستید، در ادامه با ما همراه باشید.

رابط کاربری گرافیکی

رابط کاربری گرافیکی (Graphical User Interface) که به‌اختصار با عنوان GUI شناخته می‌شود، نوعی رابط کاربری است که به کاربران امکان می‌دهد از طریق شاخص‌های تصویری و با استفاده از مواردی همچون آیکون‌ها، منوها، پنجره‎ها و... با کامپیوتر ارتباط برقرار کنند. GUI بر خلاف رابط خط فرمان (Command Line Interface) است که کاربران از طریق صفحه‌کلید و تایپ دستورات، با کامپیوتر ارتباط برقرار می‌کنند و این دشواری خود را دارد.

کتابخانه Tkinter

Tkinter ماژول داخلی پایتون است که برای ایجاد برنامه‌های GUI استفاده می‌شود. کار با Tkinter بسیار ساده است. این ماژول، جزئی از کتابخانه‌ی استاندارد پایتون است و نیازی به نصب جداگانه ندارد زیرا به همراه خود پایتون نصب می‌شود. از این رو، Tkinter یکی از پرکاربردترین ماژول‌ها برای ایجاد برنامه‌های GUI در پایتون است.

برخی دیگر از کتابخانه‌های پایتون برای ایجاد برنامه‌های GUI عبارتند از:

  • Kivy
  • Python Qt
  • wxPython

که در این میان Tkinter بیشترین کاربرد و استفاده را دارد.

ایجاد برنامه با Tkinter

ایجاد برنامه‌ی GUI با استفاده از Tkinter کار آسانی است. تمام آنچه که شما باید انجام دهید، دنبال کردن مراحل زیر است:

  • ماژول Tkinter را وارد کنید.
  • پنجره‌ی اصلی برنامه‌ی GUI را ایجاد کنید.
  • یک یا چند ابزارک را به برنامه‌ی GUI اضافه کنید.
  • حلقه‌ی رویداد اصلی را وارد کنید تا با هر اقدام کاربر، عملی انجام دهد.

مثال:

from tkinter import *                  # =================== مرحله 1

# writing code needs to
# create the main window of
# the application creating
# main window object named root
root = Tk()                             # ======================  مرحله 2

# giving title to the main window
root.title("First_Program")

# Label is what output will be
# show on the window
label = Label(root, text ="Hello World !").pack()      #===== مرحله 3

# calling mainloop method which is used
# when your application is ready to run
# and it tells the code to keep displaying
root.mainloop()                        #===================== مرحله 4

خروجی:

ابزارک‌های Tkinter

ابزارک‌ها (Widgets) در Tkinter، عناصر برنامه‌ی GUI هستند که برای تعامل کاربران با برنامه، کنترل‌های مختلفی (مانند برچسب‌ها، دکمه‌ها، منوها، چک باکس‌ها، دکمه‌های رادیویی و موارد دیگر) ارائه می‌دهند.

به طور کلی، ابزارک عنصری از رابط کاربری گرافیگی (GUI) است که اطلاعات را نمایش می‌دهد یا راهی برای تعامل کاربر با سیستم عامل فراهم می‌کند. در Tkinter، ابزارک‌ها اشیاء هستند یعنی نمونه‌هایی از کلاس‌ها که دکمه‌ها، قالب‌ها و... را نشان می‌دهد.

هر ابزارک جداگانه یک شی پایتون است. هنگام ایجاد ابزارک، باید والد آن را به عنوان یک پارامتر به تابع ایجاد ابزارک وارد کنیم. تنها استثنا، پنجره‌ی "root" است که پنجره‌ی سطح بالایی بوده، شامل همه‌ی موارد دیگر می‌شود و والد ندارد.

اگر با مباحث شی‌ءگرایی آشنایی ندارید، مقاله‌ی "آموزش برنامه نویسی شی‌گرایی در پایتون" را مطالعه کنید.

مثال:

from tkinter import *

# create root window
root = Tk()

# frame inside root window
frame = Frame(root)

# geometry method
frame.pack()

# button inside frame which is
# inside root
button = Button(frame, text ='7Learn')
button.pack()

# Tkinter event loop
root.mainloop()

کلاس ابزارک‌‌های Tkinter

در ادامه لیستی از ابزارک‌های اصلی که Tkinter از آن‌ها پشتیبانی می‌کند، به همراه توضیحات کوتاهی از کاربرد هر یک را مشاهده می‌کنید:

  • Label: برای نمایش متن یا تصویر بر روی صفحه استفاده می‌شود.
  • Button: برای افزودن دکمه‌ها به برنامه‌ی شما استفاده می‌شود.
  • Canvas: برای کشیدن تصویر و طرح‌های دیگر مانند گرافیک، متن و غیره استفاده می‌شود.
  • ComboBox: یک پیکان رو به پایین برای انتخاب گزینه‌ای از لیست گزینه‌های موجود، در اختیار کاربر قرار می‌دهد.
  • CheckButton: کاربر از طریق آن می‌تواند چندین گزینه از گزینه‌های موجود را انتخاب کند.
  • RadiButton: برای انتخاب فقط یک مورد از گزینه‌های موجود از این آیتم استفاده می‌شود.
  • Entry: برای وارد کردن متن تک‌خطی کاربر استفاده می‌شود.
  • Frame: به عنوان محلی برای نگهداری و سازمان‌دهی ابزارک‌ها استفاده می‌شود.
  • Message: کارکردی شبیه به برچسب (Label) دارد و برای متن‌های چندخطی و غیر قابل ویرایش استفاده می‌شود.
  • Scale: یک اسلایدر گرافیکی ایجاد کرده و امکان انتخاب مقدار دلخواه با جابجایی آن را می‌دهد.
  • Scrollbar: برای پیمایش به پایین محتویات استفاده می‌شود.
  • SpinBox: این امکان را به کاربر می‌دهد تا از مقادیر تعیین‌شده، مقداری را انتخاب کند.
  • Text: امکان ایجاد، ویرایش و نحوه‌ی نمایش یک متن چندخطی را به کاربر می‌دهد.
  • Menu: برای ایجاد انواع منو در برنامه استفاده می‌شود.

مدیریت هندسه ابزارک

ایجاد کردن یک ابزارک به معنی نمایش در صفحه نیست، بلکه برای نمایش آن، باید یکی از سه متد grid ،pack و یا place را فراخوانی کنیم.

  • ()pack: ابزارک‌ها را در سطرها یا ستون‎ها دسته‌بندی می‌کند.
  • ()grid: ابزارک‌ها را در یک جدول دو بعدی قرار می‌دهد.
  • ()place: به شما امکان می‌دهد، موقعیت و اندازه‌ی یک پنجره را به صورت مطلق یا نسبت به پنجره‌ی دیگر مشخص کنید.

همان‌طور که مشاهده می‌کنید، تعداد ابزارک‌های اصلی Tkinter پرشمار بوده و در این آموزش وقت کافی برای توضیح دادن هر یک وجود ندارد. لذا ما با نوشتن یک برنامه، نحوه‌ی کار کردن با Tkinter و تعدادی از ابزارک‌های آن را به شما آموزش خواهیم داد. اگر نیاز به کسب اطلاعات بیشتری در مورد ماژول Tkinter دارید، می‌توانید مستندات پایتون را مطالعه کنید.

ماشین حساب گرافیکی با Tkinter پایتون

در آموزش‌های قبلی پایتون، نحوه‌ی نوشتن ماشین حساب ساده در محیط خط فرمان را به شما آموزش دادیم که می‌توانید آن را در مقاله‌ی "برنامه ماشین حساب ساده در پایتون" مطالعه کنید. اما در اینجا فرصتی پیش آمد تا نحوه‌ی نوشتن یک ماشین حساب GUI را با پایتون آموزش دهیم. ظاهر ماشین حسابی که ما خواهیم نوشت همانند شکل زیر است:

برای این کار، مرحله به مرحله کد خود را تکمیل می‌کنیم. ابتدا، همانند مراحل بیان‌شده برای ایجاد برنامه‌ی GUI اقدام به ایجاد بدنه‌ی اصلی برنامه می‌کنیم. به این صورت:

from tkinter import *

cal = Tk()
cal.title("Calculator")

cal.mainloop()

خروجی این کد در ویندوز مانند شکل زیر است.

ایجاد نمایشگر

بعد از ایجاد کلیت برنامه GUI به سراغ ساخت اجزای یک ماشین حساب گرافیکی می‌رویم. اولین قسمت، صفحه نمایشگر ماشین حساب است. نحوه‌ی ایجاد آن به صورت زیر است:

from tkinter import *

cal = Tk()
cal.title("Calculator")
operator = ""
text_input = StringVar()

txtDisplay = Entry(cal, font=('arial', 20, 'bold'), textvariable=text_input, bd=30,
                   insertwidth=4, bg='powder blue', justify='right').grid(columnspan=4)


cal.mainloop()

در قطعه کد بالا، متغیر operator یک رشته‌ی خالی است که مقادیر وارد شده را در خود نگه می‌دارد و متغیر text_input با استفاده از متد ()StringVar کتابخانه‌ی Tkinter، ورودی را از صفحه کلید دریافت می‌کند.

برای ایجاد نمایشگر ماشین حساب باید یک شی از کلاس Entry بسازیم. در اینجا شی ما txtDisplay است که در اولین پارامتر، والد خود یعنی cal را می‌گیرید و در ادامه پارامترهایی که داده می‌شود، مربوط به ویژگی‌های (options) ابزارک است. ویژگی‌های از قبیل اندازه، فونت، رنگ، جایگاه و غیره که این نمایشگر را به شکل دلخواه شما در می‌آورد.

برای کسب اطلاعات بیشتر در مورد ویژگی‌های Entry، مستندات Tkinter را مطالعه کنید.

خروجی کد بالا در ویندوز به صورت زیر است:

ایجاد دکمه‌ها

با دکمه‌ی "7" کار خود را آغاز می‌کنیم. برای ساخت دکمه باید از کلاس Button استفاده کنیم. ابتدا شی btn7 را می‌سازیم و در اولین پارامتر، والد اصلی که همان cal است را وارد می‌کنیم و در ادامه ویژگی‌های دکمه‌ی دلخواه خود را وارد می‌کنیم. برای کسب اطلاعات بیشتر در مورد ویژگی‌های Button، مستندات Tkinter را مطالعه کنید.

from tkinter import *

cal = Tk()
cal.title("Calculator")
operator = ""
text_input = StringVar()

txtDisplay = Entry(cal, font=('arial', 20, 'bold'), textvariable=text_input, bd=30,
                   insertwidth=4, bg='powder blue', justify='right').grid(columnspan=4)

btn7 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='7').grid(row=1, column=0)

cal.mainloop()

خروجی:

همانند btn7 و با همین ویژگی‌ها، سه دکمه‌ی دیگر به نام‌های btn8 ،btn9 و addition را می‌سازیم. تنها تفاوت این سه دکمه در ویژگی text و متد grid آن‌ها است. به کدهای زیر دقت کنید:

…

btn7 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='7').grid(row=1, column=0)

btn8 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='8').grid(row=1, column=1)

btn9 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='9').grid(row=1, column=2)

addition = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
                  text='+').grid(row=1, column=3)

…

اگر این کدها را اجرا کنیم، خروجی برنامه به صورت زیر است:

حالا به همین ترتیب سایر دکمه‌های ماشین حساب را ایجاد می‌کنیم. لازم به ذکر است که به ویژگی‌های text و متد grid هر یک از این دکمه‌ها به دقت توجه کنید، تا اختلاف آن‌ها را متوجه شوید. کد نوشته‌شده‌ی ما به صورت زیر خواهد بود:

from tkinter import *

cal = Tk()
cal.title("Calculator")
operator = ""
text_input = StringVar()

txtDisplay = Entry(cal, font=('arial', 20, 'bold'), textvariable=text_input, bd=30,
                   insertwidth=4, bg='powder blue', justify='right').grid(columnspan=4)

#======================================================================================
btn7 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='7').grid(row=1, column=0)
btn8 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='8').grid(row=1, column=1)
btn9 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
                text='9').grid(row=1, column=2)
addition = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
                 text='+').grid(row=1, column=3)

#======================================================================================
btn4 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='4').grid(row=2, column=0)
btn5 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='5').grid(row=2, column=1)
btn6 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='6').grid(row=2, column=2)
subtraction = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='-').grid(row=2, column=3)

#======================================================================================
btn1 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='7').grid(row=3, column=0)
btn2 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='8').grid(row=3, column=1)
btn3 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='9').grid(row=3, column=2)
multiply = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='*').grid(row=3, column=3)

#======================================================================================
btn0 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='0').grid(row=4, column=0)
btnClear = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='C').grid(row=4, column=1)
btnEquals = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='=').grid(row=4, column=2)
division = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='/').grid(row=4, column=3)


cal.mainloop()

خروجی

کد نویسی بخش ظاهر ماشین حساب ما کامل شد و اکنون به سراغ نوشتن توابع، برای فعال شدن دکمه‌ها و نمایشگر می‌پردازیم.

نوشتن تابع btnClick

برای آن‌که دکمه‌هایی که ایجاد کرده‌ایم بتوانند عدد مورد نظر را در نمایشگر نشان دهند، لازم است تابعی بنویسیم که با وارد کردن آن در ویژگی‌های هر یک از دکمه‌ها، عدد دکمه مدنظر ما را نمایش دهد. بنابراین یک تابع به نام btnClick تعریف می‌کنیم که با استفاده از کلمه‌ی کلیدی global تغییرات ایجاد شده‌ی احتمالی را روی متغیر بیرونی operator اعمال کند.

from tkinter import *

def btnClick(numbers):
    global operator
    operator = operator + str(numbers)
    text_input.set(operator)

...

بعد از نوشتن تابع، با استفاده از ویژگی command، دکمه‌ها و با کمک یک lambda آن را در تمامی دکمه‌ها به جز دکمه‌های btnEquals و btnClear وارد می‌کنیم. برای نمونه، نحوه‌ی وارد کردن تابع در btn7 به صورت زیر است:

btn7 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='7', command=lambda:btnClick(7) ).grid(row=1, column=0)

نوشتن تابع btnClearDisplay

برای کار کردن دکمه‌ی btnClear و پاک کردن نمایشگر لازم است یک تابع مخصوص آن، همانند کد زیر بنویسیم.

...

def btnClearDisplay():
    global operator
    operator =""
    text_input.set("")

...

در اینجا نیز، با استفاده از ویژگی command، تابع نوشته شده را در ویژگی‌های دکمه‌ی btnClear وارد می‌کنیم.

...

btnClear = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
                  text='C', command= btnClearDisplay).grid(row=4, column=1)

...

تا اینجای کار، اگر برنامه را اجرا کنید، تمامی دکمه‌ها به جز دکمه‌ی btnEquals کار خواهند کرد.

نوشتن تابع btnEqualsInput

مرحله‌ی آخر، نوشتن تابعی است که حاصل محاسبات داده شده را به دست آورد. لذا تابع btnEqualsInput را تعریف می‌کنیم که در آن با استفاده از متد eval عملیات داده شده را محاسبه می‌کند. به این صورت:

...

def btnEqualsInput():
    global operator
    sumup = str(eval(operator))
    text_input.set(sumup)
    operator=""

...

در قدم آخر، تابع نوشته شده را با کمک ویژگی command به ویژگی‌های دکمه‌ی btnEquals اضافه می‌کنیم.

...

btnEquals = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
                   text='=', command=btnEqualsInput).grid(row=4, column=2)

...

کد تکمیل‌شده

به صورت مرحله به مرحله، کد نویسی یک ماشین حساب GUI را به جلو بردیم و برای این کار، از ماژول محبوب Tkinter پایتون استفاده کردیم. کد کامل شده‌ی ما به صورت زیر است:

from tkinter import *

def btnClick(numbers):
    global operator
    operator = operator + str(numbers)
    text_input.set(operator)

def btnClearDisplay():
    global operator
    operator =""
    text_input.set("")

def btnEqualsInput():
    global operator
    sumup = str(eval(operator))
    text_input.set(sumup)
    operator=""


cal = Tk()
cal.title("Calculator")
operator = ""
text_input = StringVar()

txtDisplay = Entry(cal, font=('arial', 20, 'bold'), textvariable=text_input, bd=30,
                   insertwidth=4, bg='powder blue', justify='right').grid(columnspan=4)
btn7 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='7', command=lambda:btnClick(7) ).grid(row=1, column=0)
btn8 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='8', command=lambda:btnClick(8)).grid(row=1, column=1)
btn9 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='9', command=lambda:btnClick(9)).grid(row=1, column=2)
addition = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
               text='+', command=lambda:btnClick('+')).grid(row=1, column=3)

#============================================================================
btn4 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='4', command=lambda:btnClick(4)).grid(row=2, column=0)
btn5 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='5', command=lambda:btnClick(5)).grid(row=2, column=1)
btn6 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='6', command=lambda:btnClick(6)).grid(row=2, column=2)
subtraction = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='-', command=lambda:btnClick('-')).grid(row=2, column=3)

#============================================================================
btn1 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
                 text='1', command=lambda:btnClick(1)).grid(row=3, column=0)
btn2 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='2', command=lambda:btnClick(2)).grid(row=3, column=1)
btn3 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='3', command=lambda:btnClick(3)).grid(row=3, column=2)
multiply = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='*', command=lambda:btnClick('*')).grid(row=3, column=3)

#============================================================================
btn0 = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='0', command=lambda:btnClick(0)).grid(row=4, column=0)
btnClear = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='C', command= btnClearDisplay).grid(row=4, column=1)
btnEquals = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='=', command=btnEqualsInput).grid(row=4, column=2)
division = Button(cal, padx=16, pady=16, bd=8, fg='black', font=('arial', 20, 'bold'),
              text='/', command=lambda:btnClick('/')).grid(row=4, column=3)


cal.mainloop()

اگر این کد را اجرا کنید، یک ماشین حساب ساده‌ی گرافیکی به شما نمایش داده می‌شود که با کلیک روی دکمه‌های آن، کار خواهد کرد. لازم به ذکر است، این ماشین حساب، فقط به منظور آموزش عملی Tkinter نوشته شده و هنوز نواقص و کمبودهایی دارد که شما می‌توانید برای تمرین و یادگیری بیشتر، به رفع مشکلات آن‌ بپردازید.

جمع بندی:

در این آموزش، از مفهوم رابط کاربری گرافیکی گفتیم و سپس ماژول Tkinter را برای نوشتن این‌گونه برنامه‌ها معرفی کردیم. همچنین نحوه‌ی ایجاد یک برنامه‌ی GUI با Tkinter را در پایتون آموزش داده و انواع ابزارک‌های Tkinter و کاربرد هر یک را به اختصار توضیح دادیم. در ادامه، به صورت عملی نوشتن یک ماشین حساب گرافیکی را آموزش دادیم. مباحث Tkinter فراتر از مطالب عنوان شده در این مقاله است، که در صورت علاقه‌مندی می‌توانید یادگیری آن‌ها را دنبال کنید. امیدواریم با این آموزش، رضایت شما را به دست آورده باشیم. خوشحال می‌شویم نظرات خود را در مورد برنامه نویسی برنامه‌های GUI در پایتون با ما به اشتراک بگذارید.

اگر به یادگیری بیشتر در زمینه‌ی برنامه نویسی پایتون علاقه داری، یادگیری زبان پایتون بسیار ساده است. و با شرکت در دوره‌ی متخصص پایتون توسعه وب در آینده می‌تونی اپلیکیشن موبایل و دسکتاپ بسازی و وارد حوزه‌ی هوش مصنوعی هم شوی.

چه امتیازی به این مقاله می دید؟

1 2 3 4 5

نویسنده

هیچوقت برای یادگیری دیر نیست؛ همیشه چیزهای جدید برای آموختن وجود دارد.. این دو جمله، همیشه آویزه‌ی گوش منه، چون باعث میشه از یادگیری چیزهای تازه هراسی نداشته باشم.


منبع: 7learn.com