基本Ncurses菜单

时间:2017-01-13 00:04:57

标签: c menu ncurses tui

我试图在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:代码评论不是英文的,但我希望胜利是必要的

1 个答案:

答案 0 :(得分:1)

这里有很多问题。我已经包含了一个有效的代码的修改版本,我将尝试描述这些更改。

有一些未使用的变量,即argcargvc,因此我将这些变量转换为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()