我使用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);
}
答案 0 :(得分:1)
我刚用你的代码玩了一下。
我认为主要的问题是你在整个屏幕上refresh()
,刷新窗口wrefresh (my_win)
就足够了。
第二个问题:你确实等了两次击键:
1.在while
循环中
2.在if
声明中。
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
窗口,并取消对refresh
和wrefresh
的大多数调用。 wgetch
(getch
)在正在阅读的窗口上刷新。对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;
}