ncurses: string einlesen aber gleichzeitig Sondertasten abfragen



  • Hallo,
    viele Linuxprogramme wie z.B. nano erlauben es Text einzugeben aber gleichzeitig auf Sondertasten zu reagieren. Ich versuche gerade dieses Verhalten für ein eigenes Projekt zu coden.
    Es soll ein String eingelesen werden können UND das Programm soll auch während der Eingabe auf F-Tasten reagieren können (Fensterwechsel, Abbruch, Speichern, etc.).
    Nun ist ja das Verhalten der Einlesefunktionen für Strings blockierend, das für getch() kann man nicht blockierend schreiben. Nur an der Kombination beider hapert es.
    Bislang behelfe ich mir mit einer Vorgehensweise die alle Zeichen, die ich nicht als Steuerzeichen verwende an einen String anhänge, bzw. wieder daraus entferne, schreibe diese Zeichen auf den Bildschirm und beende die Eingabe mit return.

    Die Frage: gibt es einfachere (eingebaute) Funktionen innerhalb der ncurses-Bibliothek um so ein Programmverhalten zu erreichen?
    Die Dokumentationen die ich habe beschränken sich nur auf das Einlesen von Einzelzeichen oder eben strings.

    Hier mal meine Lösung (unvollständig und der einfachheit halber C/C++ Mischmasch):

    #include <curses.h>
    #include <stdlib.h>
    #include <string>
    
    void quit() {
        endwin();
    }
    
    int main() {
        initscr();
        atexit(quit);
        noecho();
        nodelay(stdscr, TRUE);
        keypad(stdscr, TRUE); // to 
        mvprintw(0,0,"cancel with F1");
        bool finished = FALSE;
        move(1,0);    
        std::string inputstr;
        while(!finished) {
            int ch = getch();
            switch(ch) {
                case ERR:
                    napms(10);
                    break;
                case KEY_F(1):
                    return 0;
                    break;
                case 10: // 10 = RETURN
                    finished = TRUE;
                    break;
                case KEY_BACKSPACE:
                    if(inputstr.length() > 0) {
                        inputstr.pop_back();
                        int x,y;
                        getyx(stdscr, y, x);
                        move(y, x-1);
                        clrtoeol();
                        refresh();
                    }
                    break;
                default:
                    inputstr += (char)ch;
                    addch(ch);
                    refresh();
                    break;
            }
    
        }
        
        mvprintw(7,0,"The input was: %s", inputstr.c_str());
        refresh();
        napms(3000);
        return 0;
    }
    
    


  • Ich würde vermuten, du brauchst Parallelität/Nebenläufigkeit/"Threads"/Forks an i-einer Stelle.



  • Hallo Fragender,
    vielen Dank für die Richtungsweisung. Dass eine Lösung mit verschiedenen Ausführungsfäden vorgeschlagen wird habe ich schon befürchtet 😉
    So weit bin ich aktuell noch nicht in C++ vorgedrungen, ist jedoch in Arbeit.

    Das Codebeispiel funktioniert zwar im Ansatz um es jedoch gegen alle Eingabeeventualitäten zu rüsten ist noch einiges zu machen.

    Da ich diese Funktionalität für eine eigene Anwendung einsetzen möchte werde ich erstmal mit dem obigen Beispiel weitermachen und mich dann in Threadprogrammierung einlesen.


Anmelden zum Antworten