将代码从initscr()迁移至newterm()(多显示器)后,如何更新LINES和COLS?
解决newterm()迁移中的LINES/COLS与窗口调整问题
核心思路
用newterm()替代initscr()后,系统不会自动创建stdscr或维护全局LINES/COLS,你需要手动管理每个终端的根窗口、尺寸变量,以及窗口调整事件的处理逻辑。
具体实现步骤
初始化多终端与根窗口
调用newterm()时,会返回对应终端的根窗口(等价于单终端场景的stdscr),同时保存TERMINAL结构体用于多终端切换:#include <curses.h> #include <stdio.h> int main() { // 第一个显示器终端(默认stdout/stdin) WINDOW *root_win1 = newterm(NULL, stdout, stdin); TERMINAL *term1 = cur_term; // 第二个显示器终端(需指定对应tty设备,示例为/dev/tty2) FILE *term2_fd = fopen("/dev/tty2", "r+"); WINDOW *root_win2 = newterm(NULL, term2_fd, term2_fd); TERMINAL *term2 = cur_term; // 切换回第一个终端进行后续操作 set_term(term1);替代全局LINES/COLS:维护终端独立尺寸
放弃依赖全局LINES/COLS,为每个终端的根窗口单独维护尺寸变量,通过getmaxyx()实时获取:int term1_lines, term1_cols; getmaxyx(root_win1, term1_lines, term1_cols); // 创建互不重叠的子窗口 WINDOW *win_top = newwin(term1_lines/2, term1_cols, 0, 0); WINDOW *win_bottom = newwin(term1_lines/2, term1_cols, term1_lines/2, 0);处理KEY_RESIZE窗口调整事件
在主循环中捕获KEY_RESIZE,重新获取终端尺寸,用wresize()调整子窗口大小并刷新:int ch; while ((ch = wgetch(root_win1)) != KEY_F(1)) { // F1键退出 if (ch == KEY_RESIZE) { // 更新当前终端尺寸 getmaxyx(root_win1, term1_lines, term1_cols); // 调整子窗口大小与位置 wresize(win_top, term1_lines/2, term1_cols); wresize(win_bottom, term1_lines/2, term1_cols); mvwin(win_bottom, term1_lines/2, 0); // 刷新所有窗口(先根窗口,再子窗口) wclear(root_win1); wrefresh(root_win1); wrefresh(win_top); wrefresh(win_bottom); } // 其他按键逻辑... }多终端切换与资源清理
切换终端时使用set_term(),退出时用delscreen()清理每个终端的资源:// 清理资源 delwin(win_top); delwin(win_bottom); delscreen(term1); delscreen(term2); fclose(term2_fd); return 0; }
关键注意事项
- 多终端场景下,全局
LINES/COLS会被当前激活的终端覆盖,因此必须为每个终端维护独立的尺寸变量。 - 处理
KEY_RESIZE时,必须先刷新根窗口,再刷新子窗口,避免画面错乱。 - 打开非默认终端设备时,要确保程序有对应权限,且设备路径正确(不同系统可能有差异)。
内容的提问来源于stack exchange,提问作者keith bradley
相关产品推荐
相关产品推荐

