کنترل کننده رویداد

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

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

Tkinter روشی را برای برنامه نویسان فراهم کرده است تا رویدادها را مدیریت کنند. با استفاده از این روش می‌توان برای هر کنترل، توابع پایتون را به یک رویداد متصل کرد. برای کنترل رویدادها در پایتون از تابع ()bind به صورت زیر استفاده می‌شود:

widget.bind(event, handler)

می توان کنترل کننده رویداد یا Event Handling در پایتون را به این صورت توضیح داد که:

رویدادها

Tkinter برای اینکه به برنامه نویس اجازه بدهد تا مشخص کند چه رویدادهایی به چه توابعی متصل شوند، از روشی به نام دنباله رویدادها استفاده می‌کند. این دنباله ورودی اول تابع ()bind است که به صورت یک رشته با ساختار زیر می‌باشد:

<modifier-type-detail>

قسمت type بخش اصلی است. اما بخش‌های modifier و detail ضروری نیستند و در بسیاری از موارد استفاده نمی‌شوند. این دو بخش معمولاً اطلاعات اضافی را برای type فراهم می‌کنند. بخش type، نوع رویدادی که باید به تابع متصل شود را توصیف می‌کند. برای مثال اعمالی شبیه کلیک ماوس، فشردن یک کلید، یا دریافت فوکوس توسط یک کنترل. برای درک کامل، به کد زیر توجه کنید:

  1 import tkinter
  2 from tkinter import *
  3 
  4 window = tkinter.Tk()
  5 window.geometry('200x200')
  6 button = Button(window, text='Click Me!')
  7 button.pack()
  8 
  9 def showmessage(event):
 10     print("You clicked the button!")
 11 
 12 button.bind('<Button>', showmessage)
 13 
 14 window.mainloop()
 15 button.mainloop()

در کد بالا و در خطوط 4 و 5 یک پنجره با عرض و ارتفاع 200 پیکسل ایجاد و در خطوط 6 و 7 یک کنترل دکمه بر روی آن قرار داده‌ایم. در خط 7 و در داخل سازنده کلاس Button مشخص کرده‌ایم که دکمه در کجا قرار بگیرد و متن روی آن (text) چه باشد. حال به خطوط 12-9 که موضوع اصلی این درس است می‌پردازیم. در خطوط 10-9 یک تابع تعریف و در خط 12 این تابع را با استفاده از تابع ()bind به دکمه چپ ماوس وصل کرده‌ایم. همانطور که قبلاً اشاره شد، تابع ()bind می‌گوید که کدام تابع هنگام وقوع یک رویداد فراخوانی و اجرا شود. در خط 12 گفته‌ایم که وقتی بر روی یکی از دکمه های ماوس کلیک شد، فلان تابع که در اینجا ()showmessage است فراخوانی و کدهای آن اجرا شوند. حال اگر بخواهیم اگر بر روی مثلا دکمه چپ ماوس کلیک شد، تابع فراخوانی شود، باید خط 12 را به صورت زیر تغییر دهیم:

button.bind('<Button-1>', showmessage)

و اگر بخواهیم اول دکمه Shift کیبورد گرفته، و سپس با کلیک بر روی دکمه چپ ماوس، تابع فراخوانی شود، خط 12 را باید به صورت زیر بنویسیم:

button.bind('<Shift-Button-1>', showmessage)

در کدهای بالا، ‘<Shift-Button-1>’ یک رویداد است و وقتی به وقوع می پیوندد که دکمه چپ ماوس توسط کاربر فشرده شود. در ادامه لیست رویدادهای ماوس و صفحه کلید ذکر شده است:

رویدادهای ماوس

رویداد توضیح
“<ButtonPress-1>” زمانی روی می‌دهد که بر روی دکمه چپ ماوس کلیک شود.
“<ButtonPress-2>” زمانی روی می‌دهد که بر روی دکمه وسط ماوس کلیک شود.
“<ButtonPress-3>” زمانی روی می‌دهد که بر روی دکمه راست ماوس کلیک شود.
“<B1-Motion>” زمانی روی می‌دهد که دکمه چپ ماوس را فشار داده و بدون آنکه دکمه را رها کنید، ماوس را حرکت دهید.
“<B2-Motion>” زمانی روی می‌دهد که دکمه وسط ماوس را فشار داده و بدون آنکه دکمه را رها کنید، ماوس را حرکت دهید.
“<B3-Motion>” زمانی روی می‌دهد که دکمه راست ماوس را فشار داده و بدون آنکه دکمه را رها کنید، ماوس را حرکت دهید.
“<ButtonRelease-1>” زمانی روی می‌دهد که بر روی دکمه چپ ماوس رها شود.
“<ButtonRelease-2>” زمانی روی می‌دهد که بر روی دکمه وسط ماوس رها شود.
“<ButtonRelease-3>” زمانی روی می‌دهد که بر روی دکمه راست ماوس رها شود.
“<Double-Button-1>” زمانی روی می‌دهد که بر روی دکمه چپ ماوس دو بار کلیک شود.
“<Double-Button-2>” زمانی روی می‌دهد که بر روی دکمه وسط ماوس دو بار کلیک شود.
“<Double-Button-3>” زمانی روی می‌دهد که بر روی دکمه راست ماوس دو بار کلیک شود.
“<MouseWheel>” زمانی روی می‌دهد که دکمه وسط ماوس به سمت بالا یا پایین چرخانده شود.
“<Enter>” زمانی روی می‌دهد که نشانگر ماوس وارد یک کنترل شود.
“<Leave>” زمانی روی می‌دهد که نشانگر ماوس از یک کنترل خارج شود.
“<FocusIn>” زمانی روی می‌دهد که یک کنترل فوکوس بگیرد.
“<FocusOut>” زمانی روی می‌دهد که یک کنترل از حالت فوکوس خارج شود.
“<Configure>” زمانی روی می‌دهد که یک کنترل از تغییر اندازه، یا مکان دهد.

رویدادهای کیبورد

رویداد توضیح
“<Key>” زمانی روی می‌دهد که کاربر یکی از دکمه‌های کیبورد را فشار دهد.
“<Return>” زمانی روی می‌دهد که کاربر دکمه Enter را فشار دهد.
“<Backspace>” زمانی روی می‌دهد که کاربر دکمه Backspace را فشار دهد.
“<Tab>” زمانی روی می‌دهد که کاربر دکمه Tab را فشار دهد.
“<Escape>” زمانی روی می‌دهد که کاربر دکمه Escape را فشار دهد.
“<Prior>” زمانی روی می‌دهد که کاربر دکمه Page-up را فشار دهد.
“<Next>” زمانی روی می‌دهد که کاربر دکمه Page-Down را فشار دهد.
“<Up>” زمانی روی می‌دهد که کاربر دکمه جهت بالا را فشار دهد.
“<Down>” زمانی روی می‌دهد که کاربر دکمه جهت پایین را فشار دهد.
“<Left>” زمانی روی می‌دهد که کاربر دکمه جهت چپ را فشار دهد.
“<Right>” زمانی روی می‌دهد که کاربر دکمه جهت راست را فشار دهد.
“<F1>” زمانی روی می‌دهد که کاربر دکمه F1 را فشار دهد.
“<F2>” زمانی روی می‌دهد که کاربر دکمه F2 را فشار دهد.
“<a>” زمانی روی می‌دهد که کاربر دکمه a را فشار دهد.
“<b>” زمانی روی می‌دهد که کاربر دکمه b را فشار دهد.
“<c>” زمانی روی می‌دهد که کاربر دکمه c را فشار دهد.
“<Shift-Up>” زمانی روی می‌دهد که کاربر دکمه Shift را گرفته و سپس دکمه بالا را فشار دهد.
“<Alt-Up>” زمانی روی می‌دهد که کاربر دکمه Alt را گرفته و سپس دکمه بالا را فشار دهد.
“<Control-Up>” زمانی روی می‌دهد که کاربر دکمه Ctrl را گرفته و سپس دکمه بالا را فشار دهد.

شیء event

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

خواص event

خاصیت کاربرد در رویدادهای توضیح
.x,.y ماوس موقعیت فعلی نشانگر ماوس را با توجه به پنجره برنامه بر حسب پیکسل نشان می‌دهد.
.x_root,.y_root ماوس موقعیت فعلی نشانگر ماوس را با توجه به گوشه بالا و سمت چپ مانیتور بر حسب پیکسل نشان می‌دهد.
.num ماوس نشان می‌دهد که کدام دکمه ماوس فشرده شده است.
.delta ماوس مقدار 120 را برای یک یک بار چرخش دکمه وسط ماوس رو به بالا و مقدار 120- را برای یک بار چرخش رو به پایین دکمه وسط ماوس بر می گرداند و همراه با رویداد MouseWheel به کار می رود.
.time ماوس برای تشخیص فاصله بین دو بار کلیک کردن ماوس بر حسب میلی ثانیه به کار می رود.
.char کیبورد متن دکمه فشرده شده توسط کاربر را نشان می‌دهد. مثلاً اگر کاربر دکمه a را بفشارد، رشته a چاپ می‌شود. این خاصیت فقط دکمه‌های a-z، A-Z، اعداد 0-9 و نمادهای ریاضی را شامل می‌شود.
.keysym کیبورد متن دکمه فشرده شده توسط کاربر را نشان می‌دهد. مثلاً اگر کاربر دکمه a را بفشارد، رشته a چاپ می‌شود. این خاصیت تمام دکمه‌های کیبورد را شامل می‌شود.
.keysym_num کیبورد عدد متن دکمه فشرده شده توسط کاربر را نشان می‌دهد. مثلاً اگر کاربر دکمه a را بفشارد، عدد 97 چاپ می‌شود. این خاصیت تمام دکمه‌های کیبورد را شامل می‌شود.
.keycode کیبورد کد اسکی دکمه فشرده شده کیبورد را بر می‌گرداند.
.width,.height configure اندازه کنترل را بر حسب پیکسل بر می‌گرداند.

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

  1 import tkinter
  2 
  3 window = tkinter.Tk()
  4 window.geometry('200x200')
  5 
  6 def showlocation(event):
  7     print(event.x, event.y)
  8 
  9 window.bind('<Button-1>', showlocation)
 10 
 11 window.mainloop()

در خط 11، همانطور که در بحث شیء گرایی گفتیم، خاصیت‌های کلاس event را با استفاده از علامت نقطه فراخوانی می‌کنیم. حال برنامه را اجرا و بر روی قسمت‌های مختلف پنجره کلیک کنید. مشاهده می‌کنید که اعداد مختلفی در خروجی نمایش داده می‌شوند که همان موقعیت X و Y نشانگر ماوس هستند:
event-handling-in-tkinter-01
حال اگر در خط 9 کد بالا به جای رویداد ‘<Button-1>’ یک رویداد از کیبورد را به صورت زیر بنویسید:

window.bind('<Key>', showlocation)

و سپس برنامه را اجرا و بر روی قسمت های مختلف پنجره کلیک نمایید، هیچ اتفاق خاصی نمی افتد، چون خاصیت های x و y فقط برای رویدادهای ماوس تعریف شده اند. در عوض اگر خطوط 9-6 کد بالا را به صورت زیر تغییر داده :

def showchar(event):
    print(event.keysym)

window.bind('<Key>', showchar)

و برنامه اجرا و سپس بر روی یکی از دکمه های کیبورد کلیک کنید، مشاهده می کنید که اسم آن دکمه در قسمت خروجی برنامه به شما نشان داده می شود:
event-handling-in-tkinter-02
چون خاصیت keysym همراه با رویدادهای کیبورد، کاربرد دارد. در این درس با نحوه استفاده از رویدادها آشنا شدید، در درس های آینده توضیحات بیشتری در مورد آنها، ارائه می دهیم.