C,ncurses,在窗口之间切换以进行输入监听

时间:2018-02-04 02:43:16

标签: ncurses curses

我有一个ncurses的问题: 我是这样的:

FIELD *field[3];
FORM  *form;
WINDOW *mainwin;
WINDOW *win;
WINDOW *win2;
ITEM **my_items;
MENU *menu;

mainwindow = newwin(...);
win1 = newwin(...);
win2 = newwin(...);
form = new_form(field);
set_form_win(form, win1);
set_form_sub(form, derwin(win1, ...));
menu = new_menu((ITEM **)my_items); //menu hast items, etc...
set_menu_win(menu, win2);
set_menu_sub(menu, derwin(win2, 2, 28, 14, 3));
...
wrefresh(win1);
wrefresh(win2);
wrefresh(win);
refresh();
...
while(1){
    while((ch == getch()) {
        switch (ch) {
            case KEY_DOWN:
                 form_driver(form, REQ_NEXT_FIELD);
                     cur_field = current_field(form);
                     ch = field_index(cur_field);
                     if(ch == 2){
                      **** HIER I WANT TO MOVE THE "CURSOR" TO GO TO THE win2, WHERE THE MENU IS LOCATED
                     }
                 break;          
             default:
                 form_driver(form, ch);
                 break;
        }
    }
}

所以我的问题是,我如何在ncurses中的菜单和表单或其他菜单之间进行更改?如果有人可以帮忙的话会很棒。现在纠结这个问题2天......

当我尝试

while(ch == wgetch(win2) 

while(ch == wgetch(win1)

我也无法在这个窗口之间切换,或者我不知道如何......

修改 感谢您的2条评论。似乎有非常有经验的诅咒用户。所以我决定不使用额外的菜单。但是有一些表格字段,人们可以在2或morge选择之间进行选择,比如在菜单中(我最初想要实现的)?

EDIT2: 这是orgignal代码。在查看代码(编译代码)时,我的意图可能会很明确。我希望光标在最后一个表单字段中移动到菜单。 代码:

#include <stdio.h>
#include <form.h>
#include <menu.h>
#include <string.h>
#include<cstdlib>

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);

void create_box(WINDOW *p_win, char *string);

int main()
{
    FIELD *field[3];
    FIELD *cur_field;
    FORM  *my_form;
    WINDOW *my_form_win;
    WINDOW *win;
    WINDOW *menu_win;
    ITEM **my_items;
    MENU *my_menu;
    ITEM *cur_item;
    int ch, rows, cols, mrows, mcols, n_choices, i, c;



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

    /* Initialize few color pairs */
//    init_pair(1, foreground-color, background-color);
    init_pair(1, COLOR_WHITE,  COLOR_BLUE); //mainscreen
    init_pair(2, COLOR_RED,     COLOR_BLACK); //schadow
    init_pair(3, COLOR_BLUE,    COLOR_WHITE); //mainwindow
    init_pair(4, COLOR_YELLOW,  COLOR_WHITE);
    init_pair(5, COLOR_WHITE,  COLOR_RED);
    init_pair(6, COLOR_BLACK,  COLOR_WHITE);
    init_pair(7, COLOR_YELLOW, COLOR_CYAN);


    getmaxyx(stdscr,mcols, mrows); //y,x
    if (mrows < 80 || mcols < 23){
        endwin();
        printf("Terminal window to small. Must be at least 23x80.\r\n");
        char buffer[10];
        char bufferi[10];
        sprintf(buffer, "%d", mrows);
        sprintf(bufferi, "%d", mcols);
        char str[40];
        strcpy(str, "Terminal size: ");
        strcat(str, bufferi);
        strcat(str, "x");
        strcat(str, buffer);
        strcat(str, "\r\n");
        printf(str);
        return 0;
    }
    bkgd(COLOR_PAIR(1));
    refresh();
    win = newwin(mcols-5, mrows-5, 2, 2);
    wbkgd(win, COLOR_PAIR(3));
    create_box(win, "SPI-daisychain-motorcontrol");
    wrefresh(win);
    refresh();


    /* Initialize the fields */
    int beginy = 0;
    int beginx = 0;
    int formlength = 15;
    field[0] = new_field(1, formlength, beginy,     beginx, 0, 0);
    field[1] = new_field(1, formlength, beginy + 3, beginx, 0, 0);
    field[2] = new_field(1, formlength, beginy + 6, beginx, 0, 0);
    field[3] = NULL;

    /* Set field options */
    set_field_back(field[0], A_UNDERLINE);
    /* Field is filled up       */
    set_field_back(field[1], A_UNDERLINE);

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

    /* Calculate the area required for the form */
    scale_form(my_form, &rows, &cols);

    /* Create the window to be associated with the form */
    my_form_win = newwin(rows + 5, cols + 4, 4, 4);

    wbkgd(my_form_win, COLOR_PAIR(3));
    keypad(my_form_win, TRUE);

    /* Set main window and sub window */
    set_form_win(my_form, my_form_win);
    set_form_sub(my_form, derwin(my_form_win, rows, cols, 2, 1));

    /* Print a border around the main window and print a title */
    //box(my_form_win, 0, 0);
    //print_in_middle(my_form_win, 1, 0, cols + 4, "Motorcomand:", COLOR_PAIR(1));

    char *choices[] = {
            "forward",
            "backward",
    };
    n_choices = 2;
    my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));

    for(i = 0; i < n_choices; ++i)
        my_items[i] = new_item(choices[i], "");
    my_items[n_choices] = (ITEM *)NULL;

    my_menu = new_menu((ITEM **)my_items);
    //int nlines, int ncols, int begin_y, int begin_x
    menu_win = newwin(2, 9, 15, 5);
    set_menu_win(my_menu, menu_win);
    set_menu_sub(my_menu, derwin(menu_win, 2, 28, 14, 3));
    post_menu(my_menu);

    post_form(my_form);

    wattron(win, COLOR_PAIR(7));
    mvwprintw(my_form_win, beginy + 1,beginx + 1,  "Motor: [1;32]");
    mvwprintw(my_form_win, beginy + 4,beginx + 1, "Steps: [1;65500]");
    mvwprintw(my_form_win, beginy + 7,beginx + 1, "Speed (stps/s):");
    mvwprintw(my_form_win, beginy + 10,beginx + 1, "Direction:");
    wattroff(win, COLOR_PAIR(7));
    wrefresh(my_form_win);
    wrefresh(win);
    wrefresh(menu_win);

    mvprintw(LINES - 2, 0, "Use UP, DOWN arrow keys to switch between fields");

    set_current_field(my_form, field[0]);

    refresh();

    char myusedkey[10];
    while(1)
    {


        while((ch = getch()) != 'q') {
//        cur_field = current_field(my_form);
//        ch = field_index(cur_field);
//        sprintf(myusedkey, "%d", ch);
//        mvprintw(10, 30, myusedkey);

            switch (ch) {
                case KEY_DOWN:
                    /* Go to next field */


                    form_driver(my_form, REQ_NEXT_FIELD);
                    form_driver(my_form, REQ_END_LINE);

                    cur_field = current_field(my_form);
                    ch = field_index(cur_field);
                    if (ch == 0){

                    }
                    break;
                case KEY_UP:
                    /* Go to previous field */
                    form_driver(my_form, REQ_PREV_FIELD);
                    form_driver(my_form, REQ_END_LINE);
                    break;
                default:
                    refresh();
                    break;
            }


//        }

//        while(((ch = wgetch(menu_win))))
//        {
//            switch(ch)
//            {
//                case KEY_DOWN:
//                    menu_driver(my_menu, REQ_DOWN_ITEM);
//                    break;
//                case KEY_UP:
//                    menu_driver(my_menu, REQ_UP_ITEM);
//                    break;
//                case 0xA: /* Return- bzw. Enter-Taste -> ASCII-Code */
//                    if(item_index(current_item(my_menu)) == 3) {
//                        exit(0);
//                    }
//            }


//            wrefresh(my_form_win);
//            wrefresh(win);
//            wrefresh(menu_win);
//            refresh();
        }
    }

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

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
{   int length, x, y;
    float temp;

    if(win == NULL)
        win = stdscr;
    getyx(win, y, x);
    if(startx != 0)
        x = startx;
    if(starty != 0)
        y = starty;
    if(width == 0)
        width = 80;

    length = strlen(string);
    temp = (width - length)/ 2;
    x = startx + (int)temp;
    wattron(win, color);
    mvwprintw(win, y, x, "%s", string);
    wattroff(win, color);
    refresh();
}

void create_box(WINDOW *p_win, char *string) {
    int i, pos, size;
    int x, y, w, h;

    getmaxyx(p_win, w, h); //y, x
    mvwaddch(p_win, 0, 0, '+');
    mvwaddch(p_win, 0, h - 1, '+');
    mvwaddch(p_win, w - 1, h - 1, '+');
    mvwaddch(p_win, w - 1, 0, '+');
    for (i = 1; i < h - 1; i++) {
        mvwaddch(p_win, 0, i, '-');
        mvwaddch(p_win, w - 1, i, '-');
    }
    for (i = 1; i < w - 1; i++) {
        mvwaddch(p_win, i, 0, '|');
        mvwaddch(p_win, i, h - 1, '|');
    }
    size = strlen(string);
    pos = h/2-(size/2);
    mvwaddstr(p_win, 0, pos, string);


}

1 个答案:

答案 0 :(得分:0)

我是noobie,但这就是我想要使用ncurses窗口之间的制表功能的应用程序的目的。

0.5-将我所有的窗口放在一个数组中。

1-实现函数,用于读取字符并使用'getch()'使用'noecho();'对字符进行一对一处理。并使用“ putc();”或“ printw(“%c”,ch);”来打印输入的字符。这样,您可以通过某种方式处理Tab键。

2-使用“ wprintw(winarr [i],“ something”);;”之类的函数在Windows数组中传递。索引“ i”是全局变量或可以与Windows数组一起传递的指针。

所有这些都是用c而不是c ++编写的。我全力以赴寻求更好的解决方案。