使用ncurses每秒刷新屏幕一次

vuv7lop3  于 2023-01-04  发布在  其他
关注(0)|答案(2)|浏览(199)

我想每秒钟刷新一次屏幕,我正在实现一个与ncurses的聊天。
到目前为止,我有以下函数:

void print_chat(char *chat) {
    mvprintw(1, 1, "RPC Chat");
    
    move(2, 1);
    for (int i=0; i<CHAT_WIDTH; i++) {
        addch('_');
    }

    move(CHAT_HEIGHT + 3, 1);
    for (int i=0; i<CHAT_WIDTH; i++) {
        addch('_');
    }
    
    mvprintw(CHAT_HEIGHT + 5, 1, "Enter message: ");
}

它将打印以下屏幕:

在main函数中,我希望有一个循环,每1秒刷新一次屏幕,从服务器获取可能的新消息,并在该间隔内刷新屏幕,以便如果有新消息,可以显示新消息。我还希望在刷新的同时读取用户输入。我需要线程吗?
到目前为止,我在主要功能方面的尝试:

while (1) {
    print_chat(chat);
    refresh();
    sleep(1);

    chat = read_chat_from_server();
    /*char l = getch(); --> This would block the loop, waiting for input... 
}

我需要线程来实现这个吗?如果是这样,线程可以重新打印屏幕吗?还有其他方法来解决这个问题吗?

xzv2uavs

xzv2uavs1#

问题是getch()正在等待用户按回车键。
你想看一下raw(),并在得到任何输入之前调用它一次。通过调用这个函数,你可以从用户那里得到字符,而不需要他按回车键,暂停你的程序。基本上,控制台读取用户输入,打印每个字符,当用户发送'\n'**时,它会把输入返回到你的程序(参见this answer)。
你可能也想看看noecho()。类似于raw(),允许你扫描用户输入(使用getch())而不打印屏幕上的字符。这通常对让你的程序处理字符的显示方式很有用。
最后,当有更新时调用refresh()(例如,检查每一秒是否收到消息,是否发送消息等),然后调用refresh(),这是一个好主意。如果你仍然想每秒运行一次,可以尝试nodelay(stdscr, 1),其中stdscr是你的默认窗口:
nodelay选项使getch成为一个非阻塞调用。如果没有输入准备好,getch返回ERR。如果被禁用(bf为FALSE),getch等待直到一个键被按下。

8yoxcaq7

8yoxcaq72#

在首次初始化程序时,需要调用timeout()函数。
timeout(0)应使getch()不等待用户输入。

相关问题