【问题标题】:ncurses forms: Show editing cursor / highlight active fieldncurses 表单:显示编辑光标/突出显示活动字段
【发布时间】:2017-04-26 18:17:42
【问题描述】:

我是编程新手,我想用 C 中的 ncurses 实现以下功能: 一个带有要填写字段的表单,在该表单下方,用户在填写表单时会观察到一个不断变化的传感器值,从而产生所需的操作。

很高兴我做到了这一点,现在我可以通过按回车将字段缓冲区放入我的变量中,但现在我面临一个似乎无法通过 Google 搜索的问题。

我的程序从我在下面发布的示例开始。在原始示例中,我只添加了两行,它已经很好地说明了我的问题。

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

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

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

    /* 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;
}

【问题讨论】:

    标签: c forms ncurses


    【解决方案1】:

    getch 调用实质上是告诉 ncurses 将光标留在您的 mvprintw 离开它的位置 — 标准屏幕上。要让它移动到您的表单,您必须告诉它使用wgetch,并为当前表单传递WINDOW* 指针(该指针又保存了该字段的窗口位置)。

    进一步阅读:

    【讨论】:

    • 太棒了!有了一个额外的窗体 wgetch 窗口,它现在可以工作了。实际上我之前已经尝试过了,显然犯了一些错误,因此除非我按下一个键,否则该值不会更新。所以我(错误地)得出结论,wgetch 不受超时(1)的影响。非常感谢!
    【解决方案2】:

    @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;
        }
    }
    

    我希望这对其他旅行者有所帮助。有关提供的属性的更多信息,请查看this site

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      • 1970-01-01
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多