curses چیست؟
کتابخانه curses، امکانات پردازش صفحهنمایش و کیبورد مستقل از ترمینال را برای ترمینالهای مبتنی بر متن فراهم میکند؛ این ترمینالها شامل VT100s، کنسول لینوکس و ترمینال شبیهسازیشده توسط برنامههای مختلف هستند. ترمینالهای نمایش، کدهای کنترلی مختلفی را برای انجام عملیاتهای متداول مانند حرکت کرسر، اسکرول کردن صفحه و پاک کردن مناطق پشتیبانی میکنند. ترمینالهای مختلف از کدهای گسترده و متفاوتی استفاده میکنند و اغلب دارای جزئیات خاص خود هستند.
در دنیای صفحههای نمایش گرافیکی، شاید بپرسید "چرا به این موضوع اهمیت میدهیم؟" راستی که ترمینالهای نمایش سلول حروف، یک فناوری قدیمی هستند، اما در زمینههایی که امکان انجام کارهای جالب با آنها وجود دارد، همچنان ارزشمند هستند. یکی از این زمینهها شامل Unix های با اندازه کوچک یا تعبیه شده است که هیچ X serverی راهاندازی نمیکنند. زمینه دیگر ابزارهایی مانند برنامههای نصب سیستم عامل و پیکربندیکنندههای هسته هستند که ممکن است باید قبل از هرگونه پشتیبانی گرافیکی اجرا شوند.
کتابخانه curses، عملکرد پایهای را فراهم میکند و برنامهنویس را با یک انتزاع از یک صفحه نمایش حاوی چندین پنجره متنی بدون همپوشانی تأمین میکند. محتوای یک پنجره میتواند به روشهای مختلفی تغییر کند - اضافه کردن متن، پاک کردن آن، تغییر ظاهر آن و ... - و کتابخانه curses، کدهای کنترلی مورد نیاز برای ارسال به ترمینال جهت تولید خروجی مناسب را پیدا خواهد کرد. کتابخانه curses، مفاهیم رابط کاربری کاربری مانند دکمهها، جعبههای انتخاب و صندوقهای گفتگویی را فراهم نمیکند؛ اگر به این ویژگیها نیاز دارید، به یک کتابخانه رابط کاربری مانند Urwid فکر کنید.
کتابخانه curses در ابتدا برای Unix BSD نوشته شد؛ نسخههای بعدی سیستم عامل Unix از AT&T، بسیاری از تحسینبرانگیزترین و توابع جدید را اضافه کردند. کتابخانه curses BSD دیگر توسط نسخه open-source رابط AT&T یعنی ncurses به روز نمیشود. اگر از یک Unix open-source مانند Linux یا FreeBSD استفاده میکنید، سیستم شما تقریباً از ncurses استفاده میکند. با توجه به اینکه بیشتر نسخههای فعلی Unix های تجاری بر اساس کدهای System V مبتنی هستند، احتمالاً تمام توابعی که در اینجا شرح داده شدهاند در دسترس خواهند بود. با این حال، نسخههای قدیمیتر curses که توسط برخی Unixهای تجاری پشتیبانی میشوند، ممکن است از همه چیز پشتیبانی نکنند.
نسخه ویندوز پایتون شامل ماژول curses نمیباشد. نسخه UniCurses به عنوان یک پورت از این ماژول در دسترس است.
ماژول curses پایتون
ماژول پایتون یک wrapper نسبتاً ساده بر روی توابع C ارائه شده توسط curses است؛ اگر با برنامهنویسی در curses در C آشنا هستید، منتقل کردن آن دانش به پایتون واقعاً آسان است. بزرگترین تفاوت این است که رابط پایتون با ترکیب توابع مختلف C مانند addstr() و mvaddstr() و mvwaddstr()، آنها را به یک روش سادهتر از طریق یک متد addstr() تلفیق میکند. این را در جزئیات بیشتر بعداً خواهید دید.
شروع یه برنامه با curses
قبل از هر کاری، باید curses مقداردهی اولیه شود. این کار با فراخوانی تابع initscr() انجام میشود، که نوع ترمینال را تعیین میکند، کدهای مورد نیاز برای تنظیم ترمینال را به آن ارسال میکند و ساختارهای داده داخلی مختلفی را ایجاد میکند. در صورت موفقیت آمیز بودن، تابع initscr() یک شیء پنجره که نمایش تمام صفحه را نشان میدهد را برمیگرداند؛ این عموماً پس از نام متغیر C مربوطه به stdscr نامیده میشود.
import curses
stdscr = curses.initscr()
معمولاً برنامههای curses، بازتاب خودکار کلیدها را بر روی صفحه نمایش خاموش میکنند تا قادر به خواندن کلیدها باشند و فقط آنها را در شرایط خاصی نمایش دهند. برای انجام این کار، نیاز است به فراخوانی تابع noecho().
curses.noecho()
برنامهها همچنین معمولاً نیاز دارند تا به صورت فوری به کلیدها واکنش نشان دهند، بدون نیاز به فشردن کلید Enter؛ این به عنوان حالت cbreak شناخته میشود، در مقابل حالت معمول ورودی با بافر.
curses.cbreak()
ترمینالها معمولاً کلیدهای ویژه مانند کلیدهای جابجایی موشواره(فارسی را پاس بداریم!) یا کلیدهای ناوبری مانند Page Up و Home را به عنوان یک دنباله escape ارائه میدهند. در حالی که میتوانید برنامه خود را به انتظار این دنبالهها نیز بنویسید و آنها را مطابقت دهید، curses میتواند این کار را برای شما انجام دهد و مقدار خاصی مانند curses.KEY_LEFT را برگرداند. برای فعال کردن این قابلیت در curses، باید حالت keypad را فعال کنید.
stdscr.keypad(True)
خاتمه دادن به یک برنامه کورسس خیلی راحت تر از شروع آن است، فقط باید:
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
سپس تابع endwin را صدا بزنید تا ترمینال به حالت عادی باز گردد
curses.endwin()
مشکل متداولی که در هنگام اشکالزدایی یک برنامه curses پیش میآید، این است که هنگامی که برنامه بدون بازگرداندن ترمینال به حالت قبلی خود متوقف میشود، ترمینال شما بهم میریزد. این موضوع به خصوص زمانی رخ میدهد که کد شما باگ دارد و یک استثناء نامشخص بوجود میآید. به عنوان مثال، هنگامی که کلیدها را تایپ میکنید، دیگر به صفحه نمایش برنامه بازخوردی نمیدهد و این باعث سخت شدن استفاده از شل میشود.
در پایتون، میتوانید این مشکلات را برطرف کنید و فرایند اشکالزدایی را آسانتر کنید، با وارد کردن تابع curses.wrapper() و استفاده از آن به شکل زیر است:
from curses import wrapper
def main(stdscr):
# Clear screen
stdscr.clear()
# This raises ZeroDivisionError when i == 10.
for i in range(0, 11):
v = i-10
stdscr.addstr(i, 0, '10 divided by {} is {}'.format(v, 10/v))
stdscr.refresh()
stdscr.getkey()
wrapper(main)
در مقاله بعد ادامه این موضوع را خواهیم دید....