بزرگترین جشنواره سال راکت! ۵۰ درصد تخفیف شگفت انگیز!

کلیک کن!
ثانیه
دقیقه
ساعت
روز
محمد فرمانیان
2 هفته پیش توسط محمد فرمانیان مطرح شد
2 پاسخ

مشکل نمایش ansi escape code در کتابخانه curses

سلام
موقعی که یک رشته که شامل کد ansi هست رو با curses میخوام نمایش بدم، اون ها رو تفسیر نمیکنه و بصورت متن ساده نمایش میده.
کسی میدونه چکار باید کرد که کد ansi رو نمایش بده؟


ثبت پرسش جدید
آرش یدی
تخصص : امنیت بک اند
@dark25eye 2 هفته پیش مطرح شد
0

ماژول curses به‌صورت پیش‌فرض از ANSI escape codes پشتیبانی نمی‌کنه، چون خودش برای کنترل مستقیم ترمینال طراحی شده. برای اینکه بتونی متن شامل کدهای ANSI رو به‌درستی نمایش بدی، چند راه‌حل داری:

۱. استفاده از ماژول colorama به جای curses
colorama یکی از بهترین روش‌ها برای پشتیبانی از ANSI در ویندوز و لینوکس هست. اگه فقط به رنگ‌بندی نیاز داری، بهتره از این استفاده کنی:

from colorama import init, Fore

init()  # برای پشتیبانی از ANSI در ویندوز

print(Fore.RED + "این متن قرمزه!" + Fore.RESET)

اما اگه حتماً می‌خوای از curses استفاده کنی، راه‌های زیر رو امتحان کن.

۲. تفسیر دستی کدهای ANSI در curses
چون curses کدهای ANSI رو تفسیر نمی‌کنه، باید خودت رنگ‌ها رو تنظیم کنی:

import curses

def main(stdscr):
    curses.start_color()
    curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)  # تعریف رنگ قرمز روی پس‌زمینه سیاه

    stdscr.addstr("این متن بدون رنگ ANSI است\n")
    stdscr.addstr("این متن قرمز است\n", curses.color_pair(1))
    stdscr.refresh()
    stdscr.getch()

curses.wrapper(main)

۳. استفاده از blessed برای تفسیر ANSI در curses
کتابخونه‌ی blessed می‌تونه هم رنگ‌های ANSI رو حفظ کنه و هم با curses کار کنه:

from blessed import Terminal

term = Terminal()
print(term.red("این متن قرمز است!"))

اگه می‌خوای خروجی ANSI رو مستقیماً داخل curses نمایش بدی، باید ANSI رو به curses تبدیل کنی. ولی ساده‌ترین راه اینه که curses رو کنار بذاری و مستقیماً از blessed استفاده کنی.

۴. تبدیل ANSI به رنگ‌های curses (روش پیشرفته)
اگه حتماً می‌خوای داخل curses از ANSI پشتیبانی کنی، باید از re برای تبدیل کدهای ANSI به رنگ‌های curses استفاده کنی:

import curses
import re

ANSI_COLORS = {
    '31': curses.COLOR_RED,
    '32': curses.COLOR_GREEN,
    '33': curses.COLOR_YELLOW,
    '34': curses.COLOR_BLUE,
}

def strip_ansi(text):
    return re.sub(r'\x1b\[[0-9;]*m', '', text)

def parse_ansi(stdscr, text):
    curses.start_color()
    for code, color in ANSI_COLORS.items():
        curses.init_pair(int(code), color, curses.COLOR_BLACK)

    clean_text = strip_ansi(text)
    stdscr.addstr(clean_text, curses.color_pair(31))  # متن قرمز می‌شود
    stdscr.refresh()
    stdscr.getch()

def main(stdscr):
    text = "\033[31mاین متن باید قرمز باشد\033[0m"
    parse_ansi(stdscr, text)

curses.wrapper(main)

جمع‌بندی (کدوم راه بهتره؟)
✅ اگه می‌خوای ANSI به درستی نمایش داده بشه → colorama یا blessed رو جایگزین curses کن.
✅ اگه حتماً باید از curses استفاده کنی → رنگ‌ها رو با curses.init_pair مدیریت کن.
✅ اگه می‌خوای ANSI رو داخل curses تفسیر کنی → از re برای پردازش کدهای ANSI استفاده کن.


محمد فرمانیان
تخصص :
@mfa 2 هفته پیش آپدیت شد
0

@dark25eye
برنامه ای که دارم مینویسم در واقع داره یه تصویر رو از ورودی میگیره و تو ترمینال نمایش میده و چون تعداد پیکسل ها ممکنه زیاد باشه(مثلا صد ها هزار پیکسل)، همه رو یدفعه چاپ نمیکنه و تیکه تیکه چاپ میکنه و ایدم این بود که از curses استفاده کنم که همه رو addstr بزنم بعد رفرش کنم که یعدفعه نمایش بده. مشکل از جایی شروع شد که برای رنگی چاپ کردن متن از ansi استفاده میکردم و curses اون رو پردازش نمیکرد. اومدم از سیستم رنگ curses استفاده کنم که دیدم تعداد رنگ هایی که میشه تعریف کرد محدوده(256 تا) و کفاف همه رنگ های یه عکس رو نمیده(در نتیجه از روش هایی که بالا گفتی نمیتونم استفاده کنم)
اگه کتابخونه یا روشی میشناسی که این کار curses رو انجام بده و همچین مشکلاتی نداشته باشه لطفا معرفی کن.
نمونه خروجی برنامه:
 تصویر


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام