Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ncurses表单:显示编辑光标/突出显示活动字段_C_Forms_Ncurses - Fatal编程技术网

ncurses表单:显示编辑光标/突出显示活动字段

ncurses表单:显示编辑光标/突出显示活动字段,c,forms,ncurses,C,Forms,Ncurses,我是编程新手,我希望通过C语言的ncurses实现以下几点: 一个包含要填写的字段的表单,在该表单下,用户在填写表单期间将观察到一个不断变化的传感器值,这将导致所需的操作 我很高兴我做到了这一点,我现在可以通过按return将字段缓冲区放入变量中,但现在我面临一个似乎不太可能解决的问题 我的程序从下面的示例开始。在最初的示例中,我只添加了两行,它已经很好地演示了我的问题 我设置超时(1);因此getch()函数在打印新的传感器值之前不会等待表单中的用户输入。 在while循环中,我使用mvpri

我是编程新手,我希望通过C语言的ncurses实现以下几点: 一个包含要填写的字段的表单,在该表单下,用户在填写表单期间将观察到一个不断变化的传感器值,这将导致所需的操作

我很高兴我做到了这一点,我现在可以通过按return将字段缓冲区放入变量中,但现在我面临一个似乎不太可能解决的问题

我的程序从下面的示例开始。在最初的示例中,我只添加了两行,它已经很好地演示了我的问题

我设置超时(1);因此getch()函数在打印新的传感器值之前不会等待表单中的用户输入。 在while循环中,我使用mvprint输入sensor值

现在,传感器值始终是最新的,仍然可以使用箭头键从一个字段移动到另一个字段,并在字段中键入。 但可见光标总是停留在传感器值上,这对我来说是有意义的,因为它不断地移动到那里进行打印。表单驱动程序似乎记住了最后编辑的位置,因此编辑字段仍将起作用,但没有任何关于键入位置的光学提示。文档将此位置称为某一点上的“编辑光标”

我做错什么了吗?或者有没有办法突出显示该字段,甚至使编辑光标可见? 谢谢大家!

    /* gcc -Wall -pthread -g -o formncurses formncurses.c -lform -lncurses */

    #include <form.h>

    int main()
    {   FIELD *field[3];
    FORM  *my_form;
    int ch;

    /* Initialize curses */
    initscr();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    timeout(1);

    /* Initialize the fields */
    field[0] = new_field(1, 10, 4, 18, 0, 0);
    field[1] = new_field(1, 10, 6, 18, 0, 0);
    field[2] = NULL;

    /* Set field options */
    set_field_back(field[0], A_UNDERLINE);  /* Print a line for the option  */
    field_opts_off(field[0], O_AUTOSKIP);   /* Don't go to next field when this */
                        /* Field is filled up       */
    set_field_back(field[1], A_UNDERLINE); 
    field_opts_off(field[1], O_AUTOSKIP);

    /* Create the form and post it */
    my_form = new_form(field);
    post_form(my_form);
    refresh();

    mvprintw(4, 10, "Value 1:");
    mvprintw(6, 10, "Value 2:");
    refresh();

    /* Loop through to get user requests */
    while((ch = getch()) != KEY_F(1))
    {   switch(ch)
        {   case KEY_DOWN:
                /* Go to next field */
                form_driver(my_form, REQ_NEXT_FIELD);
                /* Go to the end of the present buffer */
                /* Leaves nicely at the last character */
                form_driver(my_form, REQ_END_LINE);
                break;
            case KEY_UP:
                /* Go to previous field */
                form_driver(my_form, REQ_PREV_FIELD);
                form_driver(my_form, REQ_END_LINE);
                break;
            default:
                /* If this is a normal character, it gets */
                /* Printed                */    
                form_driver(my_form, ch);
                break;
        }

    mvprintw(12, 10, "Here stands the changing sensor value");

    }

    /* Un post form and free the memory */
    unpost_form(my_form);
    free_form(my_form);
    free_field(field[0]);
    free_field(field[1]); 

    endwin();
    return 0;
}
/*gcc-Wall-pthread-g-o formncurses formncurses.c-lform-lncurses*/
#包括
int main()
{字段*字段[3];
表格*我的表格;
int-ch;
/*初始化诅咒*/
initscr();
cbreak();
noecho();
键盘(stdscr,真);
超时(1);
/*初始化字段*/
字段[0]=新的_字段(1,10,4,18,0,0);
字段[1]=新的_字段(1,10,6,18,0,0);
字段[2]=空;
/*设置字段选项*/
设置_field _back(字段[0],下划线);/*为选项打印一行*/
字段_选择_关闭(字段[0],O_AUTOSKIP);/*此操作时不转到下一个字段*/
/*字段已满*/
将字段设置回(字段[1],下划线);
字段选择关闭(字段[1],自动关闭);
/*创建表单并发布它*/
我的表格=新表格(字段);
邮寄表格(我的表格);
刷新();
mvprintw(4,10,“值1:”);
mvprintw(6,10,“值2:”);
刷新();
/*通过循环获取用户请求*/
while((ch=getch())!=KEY_F(1))
{开关(ch)
{case KEY_DOWN:
/*转到下一个字段*/
表单驱动程序(我的表单,请求下一个字段);
/*转到当前缓冲区的末尾*/
/*在最后一个字符处漂亮地离开*/
表单驱动程序(我的表单,请求结束行);
打破
案例编号:
/*转到上一字段*/
表单驱动程序(我的表单,请求上一个字段);
表单驱动程序(我的表单,请求结束行);
打破
违约:
/*如果这是一个普通字符,它会*/
/*打印*/
表格驱动程序(我的表格,ch);
打破
}
mvprintw(12,10,“此处代表变化的传感器值”);
}
/*取消post表单并释放内存*/
不受欢迎的表格(我的表格);
自由形式(我的形式);
自由_字段(字段[0]);
自由_字段(字段[1]);
endwin();
返回0;
}

调用
getch
实际上是告诉ncurses将光标留在标准屏幕上您的
mvprintw
留下的地方。要让它移动到您的表单,您必须告诉它使用
wgetch
,传递当前表单的
WINDOW*
指针(该指针反过来保持字段的窗口位置)

进一步阅读:


有一件事@Thomas的答案没有提供,那就是如何突出显示活动字段(如问题标题所示)。为了完整起见,我将在这里添加一个函数,允许您执行以下操作:

void highlight_current_field(FORM *form, FIELD *fields[])
{
    FIELD *cfield = current_field(form);
    FIELD *currfield;
    int i = 0;
    while ((currfield = fields[i]) != NULL)
    {
        if (currfield == cfield)
            set_field_back(currfield, A_STANDOUT);
        else if (i >= 4)
            set_field_back(currfield, A_UNDERLINE);

        ++i;
    }
}

我希望这能帮助同行。有关所提供属性的更多信息,请查看。

太好了!有了一个额外的窗体窗口,wgetch现在就可以开始工作了。事实上,我之前已经尝试过这个方法,显然犯了一些错误,所以除非我按下一个键,否则值不会更新。所以我(错误地)得出结论,wgetch不受超时(1)的影响。谢谢!