curses库:为什么getch()会清除我的屏幕? [英] curses library: why does getch() clear my screen?

查看:193
本文介绍了curses库:为什么getch()会清除我的屏幕?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用C ++学习curses库(pdcurses,就像我在Windows OS中一样). 我有一个显示3个窗口的程序,然后执行while循环以根据getch()捕获的按键进行一些处理.按下F1键退出循环.

但是,尽管使用wrefresh()刷新了所有三个窗口,但在我第一次输入按键之前什么也没出现.没有while循环,一切都可以正常显示.我已经进行了无数测试,就像第一次调用getch()可以完全清除屏幕,但不能完全清除后续屏幕.

我的问题是:我想念什么?起初,我以为getch()可能正在调用隐式的refresh(),但是为什么随后对其进行的调用却没有相同的行为?

非常感谢您的帮助.

这是代码.

#include <curses.h>

int main()
{
    initscr();
    raw();
    keypad(stdscr, TRUE);
    noecho();
    curs_set(0);

    WINDOW *wmap, *wlog, *wlegend;
    int pressed_key;
    int map_cursor_y = 10, map_cursor_x = 32;

    wlog = newwin(5, 65, 0, 15);
    wlegend = newwin(25, 15, 0, 0);
    wmap = newwin(20, 65, 5, 15);

    box(wmap, 0 , 0);
    box(wlog, 0 , 0);
    box(wlegend, 0 , 0);

    mvwprintw(wlog, 1, 1, "this is the log window");
    mvwprintw(wlegend, 1, 1, "legends");
    mvwaddch(wmap, map_cursor_y, map_cursor_x, '@');

    wrefresh(wlog);
    wrefresh(wmap);
    wrefresh(wlegend);

    while ((pressed_key = getch()) != KEY_F(1))
    {
         /* process keys to move the @ cursor (left out because irrelevant) */

         box(wmap, 0 , 0);
         box(wlog, 0 , 0);
         box(wlegend, 0 , 0);
         wrefresh(wmap);
         wrefresh(wlog);
         wrefresh(wlegend);
    }

    endwin();
    return 0;
}

解决方案

您的第一个直觉是正确的:getch()执行隐式refresh().具体来说,getch()等效于wgetch(stdscr),因此它是隐式的wrefresh(stdscr) -更新了您不使用的窗口(stdscr),恰好填满了屏幕.从那时起,后续调用不起作用的原因是,就诅咒而言,stdscr已经是最新的,因为您此后再也不会对其进行写(不必介意其内容已被覆盖).实际屏幕).

解决方案是在开始绘制之前在顶部显式调用refresh();或者,我更愿意在另一个窗口(最合适的一个)上调用wgetch()而不是getch(),并完全忽略stdscr的存在.只需记住,所有不允许您指定窗口的函数(getch()refresh()等)实际上都是对它们的"w"等效项的调用,其中stdscr作为隐式窗口参数./p>

I'm trying to learn the curses library (pdcurses, as I'm in Windows OS), with C++. I have a program that displays 3 windows, then a while loop to do some processing based in key presses captured by getch(). The loop gets exited when the F1 key is pressed.

However, despite refreshing all three windows with wrefresh(), nothing appears before I enter my first key press. Without the while loop, everything is displayed fine. I've made numerous tests and it's like the first call to getch() will completely clear the screen, but not the subsequent ones.

My question is: what did I miss? At first, I was thinking that maybe getch() was calling an implicit refresh(), but then why do subsequent calls to it not have the same behaviour?

Thank you very much in advance for your help.

Here is the code.

#include <curses.h>

int main()
{
    initscr();
    raw();
    keypad(stdscr, TRUE);
    noecho();
    curs_set(0);

    WINDOW *wmap, *wlog, *wlegend;
    int pressed_key;
    int map_cursor_y = 10, map_cursor_x = 32;

    wlog = newwin(5, 65, 0, 15);
    wlegend = newwin(25, 15, 0, 0);
    wmap = newwin(20, 65, 5, 15);

    box(wmap, 0 , 0);
    box(wlog, 0 , 0);
    box(wlegend, 0 , 0);

    mvwprintw(wlog, 1, 1, "this is the log window");
    mvwprintw(wlegend, 1, 1, "legends");
    mvwaddch(wmap, map_cursor_y, map_cursor_x, '@');

    wrefresh(wlog);
    wrefresh(wmap);
    wrefresh(wlegend);

    while ((pressed_key = getch()) != KEY_F(1))
    {
         /* process keys to move the @ cursor (left out because irrelevant) */

         box(wmap, 0 , 0);
         box(wlog, 0 , 0);
         box(wlegend, 0 , 0);
         wrefresh(wmap);
         wrefresh(wlog);
         wrefresh(wlegend);
    }

    endwin();
    return 0;
}

解决方案

Your first instinct was correct: getch() does an implicit refresh(). Specifically, getch() is equivalent to wgetch(stdscr), so it's an implicit wrefresh(stdscr) -- updating a window (stdscr) that you're not otherwise using, that just happens to fill the screen. The reason that subsequent calls have no effect from that point on, is that stdscr is already up to date, as far as curses is concerned, since you never write to it after that (never mind that its contents have been overwritten on the actual screen).

The solution is either to call refresh() explicitly at the top, before you begin drawing; or, my preference, to call wgetch() on a different window (whichever is most appropriate), instead of getch(), and ignore the existence of stdscr entirely. Just remember that all the functions that don't let you specify a window -- getch(), refresh(), etc. -- are really calls to their "w" equivalents, with stdscr as the implicit window parameter.

这篇关于curses库:为什么getch()会清除我的屏幕?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆