【问题标题】:Refresh screen every 1 second with ncurses使用 ncurses 每 1 秒刷新一次屏幕
【发布时间】:2023-01-03 03:44:18
【问题描述】:

我想每秒刷新一次屏幕。我正在与 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: ");
}

打印以下屏幕:

在主要功能中,我希望有一个循环,每 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... 
}

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

【问题讨论】:

标签: c ncurses


【解决方案1】:

问题是getch() 正在等待用户按回车键。

您想查看 raw() 并在获取任何输入之前调用它一次。通过调用此函数,您可以从用户那里获取字符,而无需他按回车键,从而暂停您的程序。基本上,控制台读取用户输入,打印每个正在写入的字符,然后当用户发送' ',它会将输入返回给您的程序(请参阅this answer)。

您可能也想看看noecho()。类似于 raw(),让您扫描用户输入(使用 getch())而不在屏幕上打印字符。这通常有助于让您的程序处理字符的显示方式。

最后,当某些内容更新时致电refresh() 可能是个好主意(例如,每秒检查您是否收到消息,是否发送了一条消息等),然后致电refresh()。如果您仍想每秒运行一次,可以试试nodelay(stdscr, 1),其中stdscr 是您的默认窗口:

nodelay 选项使 getch 成为非阻塞调用。如果没有输入就绪,则 getch 返回 ERR。如果禁用(bf 为 FALSE),getch 将等待直到按下某个键。

【讨论】:

  • 那么这是否意味着我不需要任何getch()?我已经尝试在循环之前调用raw(),但没有任何getch(),但程序似乎保持锁定状态,键入键时没有回显用户输入。另外,我从哪里获得用户输入?
  • 通过调用一次raw(),用户无需按回车即可接收字符。接收方式相同,使用getch(),但会立即接收。顺便说一句,你不需要线程。
  • 所以,为了澄清一下,我仍然需要在循环内进行getch()调用,它将逐个字符地读取任何输入,而不会阻塞循环,因此它可以保持每秒迭代和刷新屏幕?
  • 确切地。您需要 getch() 才能读取输入。 raw() 只是为了让用户在获得字符之前不必按回车键。
【解决方案2】:

第一次初始化程序时需要调用timeout()函数。

timeout(0) 应该导致 getch() 不等待用户输入。

【讨论】:

猜你喜欢
  • 2016-01-23
  • 2022-07-06
  • 2017-06-11
  • 2017-11-08
  • 2016-03-21
  • 2012-06-13
  • 2014-06-01
  • 2014-03-15
  • 2019-08-25
相关资源
最近更新 更多