我试图在C中做一个基本菜单。我应该用ncurses lib来做这个。我正在使用本教程: Video On YouTube
但我的版本有一些问题: 1)菜单打印不正确,只在选择菜单项时显示。然后亮点不会消失 2)菜单上的选项不会打印在顶部
你能帮帮我吗? Menu的想法是好还是我应该寻找其他教程(任何帮助?)。#include <stdio.h>
#include <ncurses.h>
#include <string.h>
#include <menu.h>
int main(int argc, char **argv)
{
int i, c;
char powitanie[]="SLOWNIK UNIWERSALNY";
int szer, dlug; //wartosci dlugosci i szerokosci terminalu
initscr(); //Inizjalizacja całości ncurses, kolory itp
raw();
noecho();
keypad(stdscr, TRUE);
start_color();
//init_pair(1, COLOR_BLUE, COLOR_BLACK); //wybór kolorów
getmaxyx(stdscr, szer, dlug); //pobranie rozmiarów terminalu
move(szer/2, (dlug-strlen(powitanie))/2); //przesuwamy kursor na środek (tak aby się ładnie wydrukowało)
//attron(COLOR_PAIR(1)); //Aktywujemy wybrane kolory
printw(powitanie); //Drukujemy powitanie
//attroff(COLOR_PAIR(1));//Dezaktywujemy kolory
refresh();//Odswiezamy (inaczej się nie wyswietli)
WINDOW * menuwin=newwin(6, dlug-12, szer-8, 6); //Definiujemy i tworzymy 'okno'
box(menuwin, 0, 0);
refresh();//ponownie odświeżamy aby okno się pojawiło
wrefresh(menuwin);//odświeżamy samo okno
keypad(menuwin, TRUE);//umozliwiamy dzialanie klawiatury w oknie
char *opcje[] = {
"Tlumacz z Polskiego na Angielski",
"Tlumacz z Angielskiego na Polski",
"Edystuj slownik",
"Wybierz slownik",
"Wyjdz",
};
int wybor;
int zaznacz=0;
while(1)//cala ta petla sluzy ciaglemu tworzeniu menu z podswietleniem wybranego elementu
{
for(i=0; i<5; i++)
{
if(i==zaznacz)
{
wattron(menuwin, A_REVERSE);
mvwprintw(menuwin, i+1, 1, opcje[i]);
wattroff(menuwin, A_REVERSE);
}
wybor = wgetch(menuwin);
switch(wybor)
{
case KEY_UP:
zaznacz--;
if(zaznacz==-1) zaznacz=0;//zabezpieczenie przed wyjsciem "poza" menu
break;
case KEY_DOWN:
zaznacz++;
if(zaznacz==5) zaznacz=4;
break;
default:
break;
}
if(wybor==10) break;
}
printw("Wybrano:%s", opcje[zaznacz]);
}
return(0);
}
PS:代码评论不是英文的,但我希望胜利是必要的
答案 0 :(得分:1)
这里有很多问题。我已经包含了一个有效的代码的修改版本,我将尝试描述这些更改。
有一些未使用的变量,即argc
,argv
和c
,因此我将这些变量转换为void
以使编译器警告静音。您可以删除c
并更改为int main(void)
,如果您愿意,可以完全删除这些变量。
我已将stdlib.h
标头文件添加到#include
功能的exit()
。这用于我添加到代码中的新错误函数fail()
。您应该始终检查在C语言编程时调用的任何函数的返回值。此处,首先检查终端是否支持使用has_colors()
函数的颜色,然后调用{{1是成功的。如果其中任何一个失败,则会调用start_color()
函数并显示错误消息,并且程序将以fail()
值退出。函数EXIT_FAILURE
返回has_colors()
,bool
函数返回start_color()
(如果成功则返回int
,否则返回OK
)。
现在颜色已经初始化,我看到菜单文本覆盖了菜单选择窗口的下边框。为了解决这个问题,我更改了窗口的大小,使其高一行:
ERR
您报告的不正确打印的根本问题是由于WINDOW * menuwin=newwin(7, dlug-12, szer-9, 6);
循环中的错误支撑控制了菜单项的打印。我借机重新组织了一下循环;现在只有一个电话for
。如果当前项目也是所选项目,则在打印前设置mvwprintw()
属性,并在打印后再次取消设置。
我还将A_REVERSE
声明中的极限测试从等值变为不等式。在这种情况下,最好使用switch
代替if (zaznacz < 0)
。
我在最终if (zaznacz == -1)
中的格式字符串的开头添加了换行符,因为有些选项太长而无法放在标题末尾的窗口中。您可以将此输出移动到任何您喜欢的位置。
最后,我在最终printw()
语句后添加了refresh()
,并在退出程序之前等待用户点击 ENTER printw()
。在退出NCurses程序之前调用getch()
进行清理非常重要。此功能可以在程序运行时反转NCurses对终端所做的更改,如果不这样做,可能会导致终端不愉快。
endwin()