2017-03-06 40 views
1

我正在制作一个具有多个窗口的应用程序,每个窗口都包含在面板内。其中一个窗口尤其必须从键盘输入。我还需要能够检测特殊键,如F键和箭头键。我目前的应用程序正在这样做。但是,即使在拨打wmove(my_wins[1], 3, 2)后,光标仍不在正确的位置。Ncurses将光标放置在正确的面板中

如何将光标移动到适当位置的正确面板上?我希望终端光标在我的第二个窗口(my_wins[1])中,在我想从中提取字符的下一个空白处。在这种情况下,这是输入该行最后一个字符后的第my_wins[1]行。

我的代码:

#include <panel.h> 
#include <ncurses.h> 
#include <string> 
#include <stdlib.h> 
#include <unistd.h> 
#include <vector> 

WINDOW *my_wins[4]; 
PANEL* my_panels[4]; 

// forward declarations 
void make_screen(); 
void clear_win1(); 
void get_input(); 

int main() 
{ 
    initscr(); 
    cbreak(); 
    noecho(); 

    make_screen(); 
    get_input(); 
    endwin(); 
} 

void get_input() 
{ 
    // enable f-keys and arrow keys 
    keypad(my_wins[1], TRUE); 

    int ch; 
    std::string str = ""; 
    std::vector<std::string> cmds; 

    while ((ch = wgetch(my_wins[1])) != KEY_F(1)) 
    { 
     switch(ch) 
     { 
      case 127: // delete 
       if (str.size() > 0) 
       { 
        str.erase(str.size()-1); 
       } 
       break; 
      case '\n': 
       cmds.push_back(str); 
       str = ""; 
       break; 
      default: 
       if (ch >= ' ' || ch <= 126) 
       { 
        str += (char) ch; 
       } 
       break; 
     } 
     clear_win1(); 
     mvwprintw(my_wins[1], 3, 2, "%s", str.c_str()); 
     wmove(my_wins[1], 3, 2+str.size()); 
     update_panels(); 
     doupdate(); 
    } 
} 

void make_screen() 
{ 
    int maxx, maxy; 
    getmaxyx(stdscr, maxy, maxx); 

    float win1y = maxy; 
    float win1x = (2.0/7)*maxx; 

    float win2y = (3.0/5)*maxy; 
    float win2x = (3.0/7)*maxx; 

    float win3y = (3.0/5)*maxy; 
    float win3x = (2.0/7)*maxx; 

    float win4y = (2.0/5)*maxy + 1; 
    float win4x = (5.0/7)*maxx; 

    my_wins[0] = newwin(win1y, win1x, 0, 0); 
    my_wins[1] = newwin(win2y, win2x, 0, win1x); 
    my_wins[2] = newwin(win3y, win3x, 0, win1x+win2x); 
    my_wins[3] = newwin(win4y, win4x, win2y, win1x); 

    /* 
    * Create borders around the windows so that you can see the effect 
    * of panels 
    */ 
    for(int i = 0; i < 4; ++i) 
    { 
     box(my_wins[i], 0, 0); 
    } 

    my_panels[0] = new_panel(my_wins[0]); 
    my_panels[1] = new_panel(my_wins[1]); 
    my_panels[2] = new_panel(my_wins[2]); 
    my_panels[3] = new_panel(my_wins[3]); 

    mvwprintw(my_wins[0], 2, 2, "Yelp data"); 
    mvwprintw(my_wins[1], 2, 2, "I/O Window"); 
    mvwprintw(my_wins[2], 2, 2, "Menu items"); 
    mvwprintw(my_wins[3], 2, 2, "Tables"); 
    mvwprintw(my_wins[3], 3, 2, "maxy: %d, maxx: %d", maxy, maxx); 
    mvwprintw(my_wins[3], 4, 2, "win1y: %f, win1x: %f", win1y, win1x); 
    mvwprintw(my_wins[3], 5, 2, "win2y: %f, win2x: %f", win2y, win2x); 
    mvwprintw(my_wins[3], 6, 2, "win3y: %f, win3x: %f", win3y, win3x); 
    mvwprintw(my_wins[3], 7, 2, "win4y: %f, win4x: %f", win4y, win4x); 
    mvwprintw(my_wins[1], 3, 2, ""); 

    update_panels(); 

    doupdate(); 
} 

void clear_win1() 
{ 
    werase(my_wins[1]); 
    box(my_wins[1], 0, 0); 
    mvwprintw(my_wins[1], 2, 2, "I/O Window"); 
    update_panels(); 
    doupdate(); 
} 

回答

1

你的示例把wmove更新到屏幕前。在更新屏幕时,这些更新将光标保留在最小光标移动的位置。

这种变化显示了如何完成你的要求:

$ diff -u foo.c.orig foo.c 
--- foo.c.orig 2017-03-06 18:56:26.000000000 -0500 
+++ foo.c  2017-03-06 19:00:03.568868347 -0500 
@@ -33,6 +33,7 @@ 
    std::string str = ""; 
    std::vector<std::string> cmds; 

+ wmove(my_wins[1], 3, 2+str.size()); 
    while ((ch = wgetch(my_wins[1])) != KEY_F(1)) 
    { 
     switch(ch) 
@@ -56,9 +57,9 @@ 
     } 
     clear_win1(); 
     mvwprintw(my_wins[1], 3, 2, "%s", str.c_str()); 
-  wmove(my_wins[1], 3, 2+str.size()); 
     update_panels(); 
     doupdate(); 
+  wmove(my_wins[1], 3, 2+str.size()); 
    } 
} 
+0

你是个好人。 –