在窗口内移动光标 - ncurses

时间:2015-04-02 11:52:29

标签: c ncurses

我使用ncurse创建了一个窗口,我试图能够使用窗口内的箭头键移动光标,只能在其中。根据我的理解,我必须使用wmove(),但显然我没有得到如何使用它。

这里有一些代码片段让你知道我做了什么:

int main(int argc, char **argv)
{
  WINDOW *my_win;
  int startx, starty, width, height;
  int ch;
  int x = 50;
  int y = 5;

  initscr();
  cbreak();
  keypad(stdscr, TRUE);
  noecho();

  height = 10;
  width = 100;
  starty = (LINES - height) / 2;
  startx = (COLS - width) / 2;
  printw("Press F1 to exit");
  refresh();
  my_win = create_newwin(25, 50, y, x);
  wmove(my_win, y, x);

  while((ch = getch()) != KEY_F(1))
    {
      if ((ch = getch()) == KEY_RIGHT)
        wmove(my_win, y++, x++);
      refresh();
  }

  endwin();
  return 0;
}
WINDOW *create_newwin(int height, int width, int starty, int startx)
{
  WINDOW *local_win;

  local_win = newwin(height, width, starty, startx);
  box(local_win, 0, 0);
  wrefresh(local_win);

  return (local_win);
}

2 个答案:

答案 0 :(得分:1)

我刚用你的代码玩了一下。

我认为主要的问题是你在整个屏幕上refresh(),刷新窗口wrefresh (my_win)就足够了。

第二个问题:你确实等了两次击键:  1.在while循环中  2.在if声明中。

while循环中的

getch()就足够了。我们可以在循环中使用ch来检测已按下的键。

我会进行switch而不是if选择:

  while((ch = getch()) != 'q')
    {
        switch (ch)
        {
          case KEY_LEFT:
            x--;
            break;
          case KEY_RIGHT:
            x++;
            break;
          case KEY_UP:
            y--;
            break;
          case KEY_DOWN:
            y++;
            break;
        }

        wmove(my_win, y, x);
        wrefresh(my_win);
    }

我还删除了一些unnessacery声明。

以下是我所做的:

#include <stdio.h>
#include <ncurses.h>

WINDOW *create_newwin(int height, int width, int starty, int startx)
{
  WINDOW *local_win = newwin(height, width, starty, startx);
  box(local_win, 0, 0);
  wrefresh(local_win);

  return (local_win);
}

int main(int argc, char **argv)
{
  WINDOW *my_win;

  int ch;
  int x = 2;
  int y = 2;

  initscr();
  cbreak();
  keypad(stdscr, TRUE);
  noecho();

  printw("Press q to exit");
  refresh();
  my_win = create_newwin(10, 20, y, x);
  wmove(my_win, y, x);
  wrefresh(my_win);

  while((ch = getch()) != 'q')
    {
        switch (ch)
        {
          case KEY_LEFT:
            x--;
            break;
          case KEY_RIGHT:
            x++;
            break;
          case KEY_UP:
            y--;
            break;
          case KEY_DOWN:
            y++;
            break;
        }

        wmove(my_win, y, x);
        wrefresh(my_win);
    }

  endwin();
  return 0;
}

如果x或y大于或小于窗口大小,则光标不会移动,但值仍会发生变化。因此,当值在窗口大小内时,请确保只允许减少或增加x和y!

提示:

case KEY_LEFT:
   if (x>0) { x--; }
   break;

答案 1 :(得分:0)

实际上,更好的解决方案是将wgetch用于my_win窗口,并取消对refreshwrefresh的大多数调用。 wgetchgetch)在正在阅读的窗口上刷新。对Zehetner的例子的改变是这样的:

--- foo3.c.orig 2015-04-02 19:53:18.000000000 -0400
+++ foo3.c      2015-04-02 19:56:31.000000000 -0400
@@ -1,11 +1,12 @@
 #include <stdio.h>
 #include <ncurses.h>

+static
 WINDOW *create_newwin(int height, int width, int starty, int startx)
 {
   WINDOW *local_win = newwin(height, width, starty, startx);
   box(local_win, 0, 0);
-  wrefresh(local_win);
+  keypad(local_win, TRUE);

   return (local_win);
 }
@@ -27,9 +28,8 @@
   refresh();
   my_win = create_newwin(10, 20, y, x);
   wmove(my_win, y, x);
-  wrefresh(my_win);

-  while((ch = getch()) != 'q')
+  while((ch = wgetch(my_win)) != 'q')
     {
         switch (ch)
         {
@@ -45,10 +45,12 @@
           case KEY_DOWN:
             y++;
             break;
+          default:
+            beep();
+            break;
         }

         wmove(my_win, y, x);
-        wrefresh(my_win);
     }

    endwin();

或(结果程序):

#include <stdio.h>
#include <ncurses.h>

static
WINDOW *create_newwin(int height, int width, int starty, int startx)
{
  WINDOW *local_win = newwin(height, width, starty, startx);
  box(local_win, 0, 0);
  keypad(local_win, TRUE);

  return (local_win);
}

int main(int argc, char **argv)
{
  WINDOW *my_win;

  int ch;
  int x = 2;
  int y = 2;

  initscr();
  cbreak();
  keypad(stdscr, TRUE);
  noecho();

  printw("Press q to exit");
  refresh();
  my_win = create_newwin(10, 20, y, x);
  wmove(my_win, y, x);

  while((ch = wgetch(my_win)) != 'q')
    {
        switch (ch)
        {
          case KEY_LEFT:
            x--;
            break;
          case KEY_RIGHT:
            x++;
            break;
          case KEY_UP:
            y--;
            break;
          case KEY_DOWN:
            y++;
            break;
          default:
            beep();
            break;
        }

        wmove(my_win, y, x);
    }

  endwin();
  return 0;
}