تابع wrapper() یک شیء قابل فراخوانی را میگیرد و عملیات اولیهای که در مقاله قبل توضیح داده شده را انجام میدهد. اگر پشتیبانی از رنگ در دسترس باشد، wrapper() رنگها را نیز مقداردهی اولیه میکند. سپس، شیء قابل فراخوانی شما اجرا میشود. پس از بازگشت از شیء قابل فراخوانی، wrapper() حالت اصلی ترمینال را بازیابی میکند. شیء قابل فراخوانی داخل یک try…except قرار دارد که استثناءها را میگیرد، حالت ترمینال را بازیابی میکند و سپس استثناء را مجدداً برمیگرداند. بنابراین ترمینال شما در صورت وقوع استثناء در وضعیت عجیب و غریبی نخواهد بود و شما میتوانید پیام و خطای استثناء را بخوانید.
پنجره ها و پد ها
پنجرهها ابزارهای اساسی در curses هستند. شیء پنجره یک منطقه مستطیلی از صفحه را نمایش میدهد و از روشهایی برای نمایش متن، پاک کردن آن، اجازه دادن به کاربر برای ورود رشته و غیره پشتیبانی میکند.
شیء stdscr که توسط تابع initscr() بازگردانده میشود، یک شیء پنجره است که تمام صفحه را پوشش میدهد. بسیاری از برنامهها فقط به این یک پنجره نیاز دارند، اما شما ممکن است بخواهید صفحه را به پنجرههای کوچکتری تقسیم کنید تا بتوانید آنها را به صورت جداگانه پاک یا بازنویسی کنید. تابع newwin() یک پنجره جدید با اندازه داده شده ایجاد میکند و شیء پنجره جدید را بازگردانده میکند.
begin_x = 20; begin_y = 7
height = 5; width = 40
win = curses.newwin(height, width, begin_y, begin_x)
توجه کنید که سیستم مختصات استفاده شده در curses غیر عادی است. مختصات همیشه به ترتیب y و x منتقل میشوند و گوشه بالا و چپ پنجره در مختصات (0،0) قرار دارد. این متفاوت با کنوانسیون عادی برای کار با مختصات است که مختصات x ابتدا آمده است. این تفاوت ناروا از بسیاری از برنامههای کامپیوتری دیگر است، اما از آنجایی که از زمان نخستین نوشتن خود curses وجود داشته است، دیگر فرصتی برای تغییر آن نیست.
برنامه شما میتواند با استفاده از متغیرهای curses.LINES و curses.COLS اندازه صفحه نمایش را تعیین کند تا اندازههای y و x را به دست آورد. مختصات معتبر از (0،0) تا (curses.LINES - 1، curses.COLS - 1) به طول میانجامد.
وقتی یک متد را برای نمایش یا پاک کردن متن فراخوانی میکنید، اثر آن به صورت فوری در صفحه نمایش نمایش داده نمیشود. به جای این، باید از متد refresh() شیء window استفاده کنید تا صفحه نمایش را بهروز کنید.
این به این دلیل است که curses در ابتدا با توجه به اتصالات ترمینال کند با سرعت 300-baud نوشته شده است؛ با این ترمینالها، کاهش زمان لازم برای بازنویسی صفحه نمایش بسیار مهم بود. به جای این، curses تغییرات در صفحه را جمعآوری کرده و آنها را با بهترین روش هنگامی که شما refresh () را فراخوانی میکنید، نمایش میدهد. به عنوان مثال، اگر برنامه شما متنی را در یک پنجره نشان داده و سپس آن پنجره را پاک کند، لازم نیست متن اصلی را ارسال کنید زیرا هرگز قابل مشاهده نخواهد بود.
در عمل، اعلام به curses برای بازکردن مجدد یک پنجره، واقعاً برنامهنویسی با curses را پیچیده نمیکند. بیشتر برنامهها در یک شور و هیجان فعالیت میکنند، سپس منتظر فشار دادن یک کلید یا عمل دیگر توسط کاربر میمانند. تنها کاری که باید انجام دهید، اطمینان حاصل کردن از بازنویسی صفحه قبل از متوقف کردن منتظر ورود کاربر است، با فراخوانی stdscr.refresh() یا متد refresh() یکی از پنجرههای مربوطه.
pad موارد خاصی از پنجره هستند؛ میتوانند بزرگتر از صفحه نمایش واقعی باشند و تنها یک بخش از pad در یک زمان نمایش داده میشود. ایجاد pad نیاز به ارتفاع و عرض pad دارد، در حالی که بازنویسی pad نیاز به دادن مختصات منطقه روی صفحه نمایش دارد که یک زیر بخش از pad در آن نمایش داده خواهد شد.
pad = curses.newpad(100, 100)
# These loops fill the pad with letters; addch() is
# explained in the next section
for y in range(0, 99):
for x in range(0, 99):
pad.addch(y,x, ord('a') + (x*x+y*y) % 26)
# Displays a section of the pad in the middle of the screen.
# (0,0) : coordinate of upper-left corner of pad area to display.
# (5,5) : coordinate of upper-left corner of window area to be filled
# with pad content.
# (20, 75) : coordinate of lower-right corner of window area to be
# : filled with pad content.
pad.refresh( 0,0, 5,5, 20,75)
فراخوانی refresh() یک بخش از pad را در مستطیلی که از مختصات (5،5) تا مختصات (20،75) در صفحه نمایش گسترش مییابد، نمایش میدهد؛ گوشه بالا و چپ بخش نمایش داده شده، مختصات (0،0) روی pad است. علاوه بر آن، pads دقیقاً مانند پنجرههای عادی هستند و از متدهای مشابه پشتیبانی میکنند.
اگر چندین پنجره و pad در صفحه نمایش داشته باشید، راهکار موثرتری برای بهروزرسانی صفحه نمایش و جلوگیری از لرزش آزاردهنده صفحه وجود دارد، هر بخش از صفحه که بهروزرسانی میشود. فراخوانی refresh() در واقع دو کار انجام میدهد:
- با فراخوانی متد noutrefresh() هر پنجره، ساختار داده زیرینی که حالت مطلوب صفحه نمایش را نشان میدهد، بهروزرسانی میشود.
- با فراخوانی تابع doupdate()، صفحه نمایش فیزیکی به گونهای تغییر میکند که با حالت مطلوبی که در ساختار داده ضبط شده است، مطابقت دارد.
به جای این، میتوانید noutrefresh() را بر روی چندین پنجره فراخوانی کنید تا ساختار داده را بهروزرسانی کنید و سپس با فراخوانی doupdate()، صفحه نمایش را بهروز کنید.
نمایش متن
از دید برنامهنویس C، curses در بعضی موارد ممکن است شبیه یک مارپیچ از تابعهایی باشد که همگی بهصورت ظریف متفاوت هستند. بهعنوان مثال، addstr() یک رشته را در محل مکان نشانگر فعلی در پنجره stdscr نمایش میدهد، در حالی که mvaddstr() ابتدا به یک مختصات y و x مشخص شده حرکت میکند و سپس رشته را نمایش میدهد. waddstr() دقیقاً مانند addstr() است، اما اجازه میدهد یک پنجره مشخص شود که به جای استفاده از پیشفرض stdscr استفاده شود. همچنین mvwaddstr() اجازه میدهد هم یک پنجره و هم یک مختصات مشخص شود.
به خوشبختی، رابط پایتون همه این جزئیات را پنهان میکند. stdscr مانند هر پنجره دیگری، یک شیء است و متدهایی مانند addstr() فرمهای مختلف آرگومان را پذیرفته و اجرا میکنند. بهطور معمول، چهار فرم مختلف وجود دارد.
- str or ch --------> رشته str یا کاراکتر ch را در موقعیت فعلی نمایش دهید
- str or ch, attr -------> رشته str یا کاراکتر ch را با استفاده از ویژگی attr در موقعیت فعلی نمایش دهید
- y, x, str or ch -------> به موقعیت y،x در پنجره بروید و str یا ch را نمایش دهید
- y, x, str or ch, attr --> به موقعیت y,x در پنجره بروید و str یا ch را با استفاده از ویژگی attr نمایش دهید
ویژگیها به شما اجازه میدهند که متن را با فرمهای برجستهتری مانند قلمهای Boldface، زیر خط، معکوس و یا با رنگ نمایش دهید. جزئیات بیشتر در بخش بعدی توضیح داده میشوند.
متد addstr() یک رشته پایتون یا رشته بایتبندی را به عنوان مقداری که باید نمایش داده شود، میپذیرد. محتویات رشتههای بایتبندی بهصورت همانطور که هست، به ترمینال ارسال میشوند. رشتهها با استفاده از مقدار ویژگی کدگذاری پنجره، به بایت کدگذاری میشوند؛ این مقدار به صورت پیشفرض به کدگذاری سیستم پیشفرض بازگردانده شده توسط locale.getencoding() است.
متدهای addch() یک کاراکتر را دریافت میکنند که میتواند یا یک رشته با طول 1، یک رشته بایتبندی با طول 1، یا یک عدد صحیح باشد.
ثابتها برای کاراکترهای اضافی در اختیار شما قرار داده شدهاند؛ این ثابتها عددهای صحیح بزرگتر از 255 هستند. به عنوان مثال، ACS_PLMINUS یک نماد +/- است و ACS_ULCORNER گوشه سمت چپ بالای یک جعبه است (برای رسم مرزها مناسب است). همچنین میتوانید از کاراکتر مناسب یونیکد استفاده کنید.
پنجرهها مکانی را که نشانگر پس از آخرین عملیات باقی مانده، بهخاطر میسپارند، بنابراین اگر مختصات y و x را حذف کنید، رشته یا کاراکتر در هرجایی که آخرین عملیات به پایان رسیده است، نمایش داده خواهد شد. همچنین میتوانید با استفاده از متد move(y،x) نشانگر را حرکت دهید. به دلیل اینکه برخی ترمینالها همیشه یک نشانگر فلشینگ را نمایش میدهند، ممکن است بخواهید اطمینان حاصل کنید که نشانگر در موقعیتی قرار داده شده که خللی ندارد؛ این ممکن است باعث گیجکنندگی شود که نشانگر در یک موقعیت دلخواه مربوط به پایاننامهای باقی بماند.
اگر برنامه شما اصلاً به نشانگر فلشینگ نیاز ندارد، میتوانید curs_set(False) را برای نامرئی کردن آن فراخوانی کنید. برای سازگاری با نسخههای قدیمیتر curses، تابع leaveok(bool) وجود دارد که هم مترادف با curs_set() است. وقتی bool درست است، کتابخانه curses سعی میکند نشانگر فلشینگ را خاموش کند و شما نیازی به نگرانی درباره باقی ماندن آن در موقعیتهای عجیب و غریب نخواهید داشت.
صفات و رنگ ها
کاراکترها میتوانند به روشهای مختلفی نمایش داده شوند. خطوط وضعیت در برنامههای مبتنی بر متن معمولاً به صورت معکوس یا یک نمایشدهنده متن ممکن است نیاز داشته باشد تا برخی از کلمات را برجسته کند. curses با امکان مشخص کردن ویژگی برای هر سلول روی صفحه، این قابلیت را پشتیبانی میکند.
منتظر ادامه اش باشید....