【问题标题】:Ncurses wrefresh not showing window bordersNcurses wrefresh 不显示窗口边框
【发布时间】:2020-06-28 21:31:11
【问题描述】:

我正在使用 ncurses 尝试一些 C++,但在显示窗口边框时遇到了问题,但在使用以下程序时遇到了问题。

#include <cstdio>
#include <cstdlib>
#include <ncurses.h>

int main(int argc, char **argv)
{
    if(argc != 5)
    {
        printf("not enough arguments\n"); 
        exit(1); 
    }
    int height = atoi(argv[1]); 
    int width = atoi(argv[2]); 
    int y = atoi(argv[3]);
    int x = atoi(argv[4]); 

    initscr(); 
    WINDOW *win = newwin(height, width, y, x);  
    box(win, 0, 0); 
    wrefresh(win); 

    int py, px; 
    getparyx(win, py, px); 
    mvprintw(LINES-2, 0, "getparyx: (%d, %d)", py, px); 

    int by, bx; 
    getbegyx(win, by, bx); 
    mvprintw(LINES-1, 0, "getbegyx: (%d, %d)", by, bx); 


    getch(); 
    delwin(win); 
    endwin(); 
}

在上面的程序中,我使用box 绘制边框并使用wrefresh 刷新,但它没有显示任何内容。但是,我打印到 stdscr 的其他内容确实显示了。

但是在另一个程序中,我能够让边框正常工作。

#include <ncurses.h>

int main() 
{
    const int height = 6, width = 8; 

    WINDOW *win; 
    int starty, startx; 
    int ch; 

    initscr(); 
    cbreak(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    starty = (LINES - height) / 2; 
    startx = (COLS - width) / 2; 
    win = newwin(height, width, starty, startx); 
    box(win, 0, 0); 
    wrefresh(win); 

    while((ch = getch()) != KEY_F(1)) 
    {
        wborder(win, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); 
        wrefresh(win); 
        delwin(win); 
        switch(ch) 
        {
            case KEY_UP: 
                win = newwin(height, width, --starty, startx);                 
                break; 
            case KEY_DOWN:
                win = newwin(height, width, ++starty, startx); 
                break; 
            case KEY_LEFT: 
                win = newwin(height, width, starty, --startx); 
                break; 
            case KEY_RIGHT:
                win = newwin(height, width, starty, ++startx); 
                break; 
        }
        move(starty + (height / 2) - 1, startx + (width / 2) - 1); 
        box(win, 0, 0); 
        wrefresh(win); 
    }

    delwin(win); 
    endwin(); 
}

问题是边框只出现在循环中。换句话说,直到我按下按钮,边框才会开始显示,这意味着最初的 wrefresh 不起作用。

在做了一些研究之后,我this 线程建议在initscr 之后(或至少在wrefresh() 之前)调用refresh,但这不起作用。那么我错过了什么边框没有在第一个程序中显示?

【问题讨论】:

  • 关于; printf("not enough arguments\n"); 1) 错误消息应该输出到stderr,而不是stdout。 2) 此错误消息未能告诉用户(和我们)参数列表应该是什么。建议以fprintf( stderr, "USAGE: %s &lt;list of arguments, separated by spaces&gt;\n". argv[0] );开头
  • 参数应该是高度、宽度、y和x。我很确定这很明显。我没有写正确的错误消息,因为我只是在测试。但是感谢您向我展示了报告错误的正确方法。之前知道stderr,但不知道如何正确使用。

标签: c++ c ncurses


【解决方案1】:

对于我的测试,最初的refresh() 肯定是缺少的。我检查了一些我写的旧代码,它确实调用了refresh() 作为 ncurses 初始化的一部分。将此添加到您的代码中使其对我有用。许多 curses 文档仍然受限于书籍,从未真正发布到网络上。

initscr();
refresh();          // <-- HERE

WINDOW *win = newwin( height, width, y, x );  
box( win, 0, 0 );
wrefresh(win);

我认为在调用第一个 refresh() 之前,窗口模型不会完全初始化。但我找不到任何关于确切为什么会这样的文档。

所以这个答案没有太多细节,对不起......但我希望它有所帮助。

【讨论】:

  • 这行得通。也许我拼错了refresh,出于某种原因,C 决定不抱怨它。我正在研究 2005 年制作的手册页和指南,因此您可以想象这是多么令人沮丧。
  • 我还想我在某处读到 getch 刷新屏幕,所以也许这就是后一个代码起作用的原因。
【解决方案2】:

手册页回答了这个问题:

initscr 还会导致第一次调用 refresh(3x) 清除屏幕。

如果窗口不是 pad,并且自 最后一次调用 wrefresh,wrefresh 将在另一个字符之前调用 被读取。

  • initscr(清除)和mvprintw 调用更新stdscr,当您调用getch 时,它最终刷新stdscr 是一个窗口,正如wrefresh 的讨论中所指出的,物理屏幕按照应用刷新的顺序进行更新(也就是说,它与另一个窗口重叠,如果您希望另一个窗口出现,请先刷新stdscr,进行清空操作)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2011-01-29
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 2018-08-15
    相关资源
    最近更新 更多