更改未在ncurses的字段中显示 [英] changes not showing in field in ncurses

查看:52
本文介绍了更改未在ncurses的字段中显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ncurses程序,它是一个登录菜单,我使用字段来输入用户名和密码.
问题是,当我在字段中键入内容时,字符会注册,但不会显示在终端中.换句话说,如果您执行代码打击并键入内容,您将无法在终端中看到它,但是如果按F2键,您可能会看到字符已注册.
这是我的代码:
test.cpp

I have a ncurses program which is a login menu and I use field for username and password.
The problem is that when I type something in the fields, characters register but do not show in terminal. In other word if you execute the code blow and type something, you won't be able to see it in terminal but if you push F2, you could see that the characters were registered.
Here is my code:
test.cpp

#include <curses.h>
#include <form.h>
#include <menu.h>
#include <string>
#include <cstring>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

class WelcomeMenu {
private:
  int _row; // number of rows of the terminal
  int _col; // number of columns of the terminal
public:
  WelcomeMenu();
  ~WelcomeMenu();
  void welcomeBox();
  void loginMenu();
  void registerMenu();
};

WelcomeMenu::WelcomeMenu(){
  initscr();
  noecho();
  cbreak();
  keypad(stdscr, true);
  int row, col;
  getmaxyx(stdscr,row,col);   /* get the number of rows and columns */
  this->_row = row; this->_col = col;
  loginMenu();
}

WelcomeMenu::~WelcomeMenu(){
  refresh();
  endwin();
}

/*
 * This is useful because ncurses fill fields blanks with spaces.
 */
char* trim_whitespaces(char *str)
{
  char *end;

  // trim leading space
  while(isspace(*str))
    str++;

  if(*str == 0) // all spaces?
    return str;

  // trim trailing space
  end = str + strnlen(str, 128) - 1;

  while(end > str && isspace(*end))
    end--;

  // write new null terminator
  *(end+1) = '\0';

  return str;
}

void WelcomeMenu::loginMenu(){
  // erase();
  FORM *form;
  FIELD *fields[5];
  WINDOW *win_body, *win_form;

  int ch;

  win_body = newwin(24, 80, 0, 0);
  assert(win_body != NULL);
  box(win_body, 0, 0);
  win_form = derwin(win_body, 20, 78, 3, 1);
  assert(win_form != NULL);
  box(win_form, 0, 0);
  mvwprintw(win_body, 1, 2, "Press F1 to quit and F2 to print fields content");

  fields[0] = new_field(1, 10, 0, 0, 0, 0);
  fields[1] = new_field(1, 40, 0, 15, 0, 0);
  fields[2] = new_field(1, 10, 2, 0, 0, 0);
  fields[3] = new_field(1, 40, 2, 15, 0, 0);
  fields[4] = NULL;
  assert(fields[0] != NULL && fields[1] != NULL && fields[2] != NULL && fields[3] != NULL);

  set_field_buffer(fields[0], 0, "Username: ");
  set_field_buffer(fields[1], 0, "username");
  set_field_buffer(fields[2], 0, "Password: ");
  set_field_buffer(fields[3], 0, "password");

  set_field_opts(fields[0], O_VISIBLE | O_PUBLIC | O_AUTOSKIP);
  set_field_opts(fields[1], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE);
  set_field_opts(fields[2], O_VISIBLE | O_PUBLIC | O_AUTOSKIP);
  set_field_opts(fields[3], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE);

  set_field_back(fields[1], A_UNDERLINE);
  set_field_back(fields[3], A_UNDERLINE);

  form = new_form(fields);
  assert(form != NULL);
  set_form_win(form, win_form);
  set_form_sub(form, derwin(win_form, 18, 76, 1, 1));
  post_form(form);

  refresh();
  wrefresh(win_body);
  wrefresh(win_form);

  while ((ch = getch()) != KEY_F(1)){

    switch (ch) {
      case KEY_F(2):
        // Or the current field buffer won't be sync with what is displayed
        form_driver(form, REQ_NEXT_FIELD);
        form_driver(form, REQ_PREV_FIELD);
        move(LINES-3, 2);

        for (int i = 0; fields[i]; i++) {
          printw("%s", trim_whitespaces(field_buffer(fields[i], 0)));

          if (field_opts(fields[i]) & O_ACTIVE)
            printw("\"\t");
          else
            printw(": \"");
        }

        refresh();
        pos_form_cursor(form);
        break;

      case KEY_DOWN:
        form_driver(form, REQ_NEXT_FIELD);
        form_driver(form, REQ_END_LINE);
        break;

      case KEY_UP:
        form_driver(form, REQ_PREV_FIELD);
        form_driver(form, REQ_END_LINE);
        break;

      case KEY_LEFT:
        form_driver(form, REQ_PREV_CHAR);
        break;

      case KEY_RIGHT:
        form_driver(form, REQ_NEXT_CHAR);
        break;

      // Delete the char before cursor
      case KEY_BACKSPACE:
      case 127:
        form_driver(form, REQ_DEL_PREV);
        break;

      // Delete the char under the cursor
      case KEY_DC:
        form_driver(form, REQ_DEL_CHAR);
        break;

      default:
        form_driver(form, ch);
        break;
    }
  }

  wrefresh(win_form);

  unpost_form(form);
  free_form(form);
  free_field(fields[0]);
  free_field(fields[1]);
  free_field(fields[2]);
  free_field(fields[3]);
  delwin(win_form);
  delwin(win_body);
}

int main(){
  WelcomeMenu * myConWin = new WelcomeMenu();
  delete myConWin;
  return 0;
}

您可以像这样编译它: g ++ -inccurses -lform test.cpp

you can compile it like: g++ -lncurses -lform test.cpp

预先感谢您的回复

推荐答案

该示例的基本问题是它不提供显示字符的功能.在ncurses中,可以使用 form_driver 函数:

The basic problem with the example is that it does not provide for displaying the characters. In ncurses, that would be done using the form_driver function:

form_driver

   Once a form has been posted (displayed), you should funnel input events
   to it through form_driver.  This routine has three major input cases:

   o   The input is a form navigation request.  Navigation  request  codes
       are constants defined in <form.h>, which are distinct from the key-
       and character codes returned by wgetch(3x).

   o   The input is a printable character.   Printable  characters  (which
       must  be positive, less than 256) are checked according to the pro-
       gram's locale settings.

   o   The input is the KEY_MOUSE special key  associated  with  an  mouse
       event.

让程序使用 form_driver 会涉及到程序的一些重组,将切换语句移动到可以从表单驱动器调用的函数中.

Making your program use form_driver would involve some reorganization of the program, moving that switch-statement into a function which can be called from the form-driver.

ncurses示例包括一些使用 form_driver的示例 .您可能想通读测试代码,看看

The ncurses examples include a few using form_driver. You might want to read through the test-code, seeing how the basic loop


 while (!finished) {
     switch (form_driver(form, c = form_virtualize(form, w))) {
     case E_OK:
          MvAddStr(5, 57, field_buffer(secure, 1));
          clrtoeol();
          refresh();
          break;
     case E_UNKNOWN_COMMAND:
          finished = my_form_driver(form, c);
          break;
     default:
          beep();
          break;
     }

使用其 form_virtualize 函数读取字符(或表单请求).您未看到的可打印字符由 form_driver 处理,后者会更新表单上的当前字段.您可以像 form_virtualize 一样操作字段缓冲区并执行其他特殊操作,但是更新表单中的字段是为什么要使用 form_driver 的原因

uses its form_virtualize function to read characters (or form-requests). The printable characters that you are (not) seeing are handled by form_driver which updates the current field on the form. You can manipulate the field-buffer and do other special things as done in form_virtualize, but updating fields in the form is why you would use form_driver.

这篇关于更改未在ncurses的字段中显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆