使用管道或重定向时 Ncurses 闪烁
Ncurses flickers when using pipes or redirection
Ncurses 在使用 "unix pipes" 和 "redirection" 输入时闪烁。也就是说,如果我输入自己但在使用“|”时却没有,它会很好地绘制或“<”。
我认为这可能是由于getch()
延迟模式(无延迟、半延迟和无限延迟)。所以我明确地尝试设置 nodelay(stdscr, FALSE);
但很明显,它没有解决它。
这是最小的工作代码:
#include <ncurses.h>
#include <stdlib.h>
#include <string.h>
/* Default assumptions */
#define BUFSIZE 100
#define SELINDICATOR ">>> "
#define MAXITEMS LINES /* Decides how many items are shown at a time. By default, it's (number of rows - 1) */
/* Declarations */
static void draw(char **data, short index, short selected);
static void handleInput(short *selected, short index);
int main(int argc, char *argv[]) {
char buf[BUFSIZE], **data;
short index = 0, selected = 1;
size_t curSize = 0;
/* Get the entries */
while(fgets(buf, BUFSIZE, stdin)) {
if(!(data = realloc(data, (curSize += sizeof(char *))))) {
fprintf(stderr, "error reallocating memory!\n");
exit(1);
}
if(!(data[index] = malloc(BUFSIZE))) {
fprintf(stderr, "error reallocating memory!\n");
exit(1);
}
strcpy(data[index], buf);
index++;
}
/* Start nCurses */
initscr();
noecho();
nodelay(stdscr, FALSE); // just tryin' it out if it works
while(1) {
draw(data, index, selected);
handleInput(&selected, index);
}
/* Quit nCurses */
endwin();
/* Free allocated memories */
for(short i = 0; i < index; i++)
free(data[i]);
free(data);
return 0;
}
void
draw(char **data, short index, short selected) {
static short posX = strlen(SELINDICATOR), posY; /* posY doesn't need to be static but it makes no difference and looks cleaner */
/* Clear old garbage */
clear();
posY = 0;
/* Draw line echoing inputs */
mvaddch(posY, 0, '>');
posY++;
/* Draw the entries */
for(short i = 0; posY < COLS && i < index; i++) {
if(posY == selected) {
mvprintw(posY, 0, SELINDICATOR);
}
mvprintw(posY, posX, "%s", data[i]);
refresh();
posY++;
}
/* Make the output visible */
refresh();
}
void
handleInput(short *selected, short numOfEntries) {
int input = getch();
/* A whole bunch of other stuff........ */
endwin();
exit(0);
}
非常感谢您的努力!
这个例子缺少一些东西,因为这个函数
void
handleInput(short *selected, short numOfEntries) {
int input = getch();
/* A whole bunch of other stuff........ */
endwin();
exit(0);
}
将在 运行 后退出一次。这留下了很多可能性,最有可能的是你 运行 这个程序很多次,导致它初始化屏幕(并且在很多终端上,switching to/from 备用屏幕 )。每次都会闪烁...
Ncurses 是作为提供交互式 用户界面的工具而设计和构建的。在某种程度上,它从标准输入(而不是直接从终端)读取输入,基于 ncurses 的程序可以将其输入从文件或管道重定向,但不清楚为什么它很重要在这种情况下实际显示 UI 。如果这样做会导致不需要的视觉效果,那么最简单的缓解措施可能是在这种情况下禁用 UI。
在问题中提供的程序中,显示 UI 似乎与读取和处理输入完全分开,并且读取输入仅最低限度地依赖于 ncurses。修改这样的程序以使其能够在 UI 和 no-UI 模式之间切换应该非常简单,我建议您这样做。为此,您可能会发现 isatty()
函数可用于确定标准输入(和/或标准输出)是否为终端。
Ncurses 在使用 "unix pipes" 和 "redirection" 输入时闪烁。也就是说,如果我输入自己但在使用“|”时却没有,它会很好地绘制或“<”。
我认为这可能是由于getch()
延迟模式(无延迟、半延迟和无限延迟)。所以我明确地尝试设置 nodelay(stdscr, FALSE);
但很明显,它没有解决它。
这是最小的工作代码:
#include <ncurses.h>
#include <stdlib.h>
#include <string.h>
/* Default assumptions */
#define BUFSIZE 100
#define SELINDICATOR ">>> "
#define MAXITEMS LINES /* Decides how many items are shown at a time. By default, it's (number of rows - 1) */
/* Declarations */
static void draw(char **data, short index, short selected);
static void handleInput(short *selected, short index);
int main(int argc, char *argv[]) {
char buf[BUFSIZE], **data;
short index = 0, selected = 1;
size_t curSize = 0;
/* Get the entries */
while(fgets(buf, BUFSIZE, stdin)) {
if(!(data = realloc(data, (curSize += sizeof(char *))))) {
fprintf(stderr, "error reallocating memory!\n");
exit(1);
}
if(!(data[index] = malloc(BUFSIZE))) {
fprintf(stderr, "error reallocating memory!\n");
exit(1);
}
strcpy(data[index], buf);
index++;
}
/* Start nCurses */
initscr();
noecho();
nodelay(stdscr, FALSE); // just tryin' it out if it works
while(1) {
draw(data, index, selected);
handleInput(&selected, index);
}
/* Quit nCurses */
endwin();
/* Free allocated memories */
for(short i = 0; i < index; i++)
free(data[i]);
free(data);
return 0;
}
void
draw(char **data, short index, short selected) {
static short posX = strlen(SELINDICATOR), posY; /* posY doesn't need to be static but it makes no difference and looks cleaner */
/* Clear old garbage */
clear();
posY = 0;
/* Draw line echoing inputs */
mvaddch(posY, 0, '>');
posY++;
/* Draw the entries */
for(short i = 0; posY < COLS && i < index; i++) {
if(posY == selected) {
mvprintw(posY, 0, SELINDICATOR);
}
mvprintw(posY, posX, "%s", data[i]);
refresh();
posY++;
}
/* Make the output visible */
refresh();
}
void
handleInput(short *selected, short numOfEntries) {
int input = getch();
/* A whole bunch of other stuff........ */
endwin();
exit(0);
}
非常感谢您的努力!
这个例子缺少一些东西,因为这个函数
void
handleInput(short *selected, short numOfEntries) {
int input = getch();
/* A whole bunch of other stuff........ */
endwin();
exit(0);
}
将在 运行 后退出一次。这留下了很多可能性,最有可能的是你 运行 这个程序很多次,导致它初始化屏幕(并且在很多终端上,switching to/from 备用屏幕 )。每次都会闪烁...
Ncurses 是作为提供交互式 用户界面的工具而设计和构建的。在某种程度上,它从标准输入(而不是直接从终端)读取输入,基于 ncurses 的程序可以将其输入从文件或管道重定向,但不清楚为什么它很重要在这种情况下实际显示 UI 。如果这样做会导致不需要的视觉效果,那么最简单的缓解措施可能是在这种情况下禁用 UI。
在问题中提供的程序中,显示 UI 似乎与读取和处理输入完全分开,并且读取输入仅最低限度地依赖于 ncurses。修改这样的程序以使其能够在 UI 和 no-UI 模式之间切换应该非常简单,我建议您这样做。为此,您可能会发现 isatty()
函数可用于确定标准输入(和/或标准输出)是否为终端。