2011-09-25 18 views

risposta

5

Qt non gestisce gli eventi della console, può solo leggere \n -le righe terminate dalla console.

È necessario utilizzare API native o altre librerie (curses).

+0

grazie per l'aiuto –

5

Ecco una soluzione alternativa per linux. L'utilizzo di questi messaggi

Capture characters from standard input without waiting for enter to be pressed https://stackoverflow.com/a/912796/2699984

che ho fatto in questo modo:

ConsoleReader.h

#ifndef CONSOLEREADER_H 
#define CONSOLEREADER_H 

#include <QThread> 

class ConsoleReader : public QThread 
{ 
    Q_OBJECT 
signals: 
    void KeyPressed(char ch); 
public: 
    ConsoleReader(); 
    ~ConsoleReader(); 
    void run(); 
}; 

#endif /* CONSOLEREADER_H */ 

ConsoleReader.cpp

#include "ConsoleReader.h" 
#include <stdio.h> 
#include <unistd.h> 
#include <termios.h> 

static struct termios oldSettings; 
static struct termios newSettings; 

/* Initialize new terminal i/o settings */ 
void initTermios(int echo) 
{ 
    tcgetattr(0, &oldSettings); /* grab old terminal i/o settings */ 
    newSettings = oldSettings; /* make new settings same as old settings */ 
    newSettings.c_lflag &= ~ICANON; /* disable buffered i/o */ 
    newSettings.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */ 
    tcsetattr(0, TCSANOW, &newSettings); /* use these new terminal i/o settings now */ 
} 

/* Restore old terminal i/o settings */ 
void resetTermios(void) 
{ 
    tcsetattr(0, TCSANOW, &oldSettings); 
} 

/* Read 1 character without echo */ 
char getch(void) 
{ 
    return getchar(); 
} 

ConsoleReader::ConsoleReader() 
{ 
    initTermios(0); 
} 

ConsoleReader::~ConsoleReader() 
{ 
    resetTermios(); 
} 

void ConsoleReader::run() 
{ 
    forever 
    { 
     char key = getch();   
     emit KeyPressed(key); 
    } 
} 

E poi basta iniziare nuovo thread per leggere le chiavi:

ConsoleReader *consoleReader = new ConsoleReader(); 
connect (consoleReader, SIGNAL (KeyPressed(char)), this, SLOT(OnConsoleKeyPressed(char))); 
consoleReader->start(); 

* aggiornamento (aggiunto il ripristino delle impostazioni del terminale su Quit)

3

Se è necessario solo 'quit' forse il seguente frammento aiuterà (c + +11 e qt5 richiesti):

#include <iostream> 
#include <future> 

#include <QCoreApplication> 
#include <QTimer> 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication application(argc, argv); 
    bool exitFlag = false; 

    auto f = std::async(std::launch::async, [&exitFlag]{ 
     std::getchar(); 
     exitFlag = true; 
    }); 

    QTimer exitTimer; 
    exitTimer.setInterval(500); 
    exitTimer.setSingleShot(false); 

    QObject::connect(&exitTimer, 
        &QTimer::timeout, 
        [&application,&exitFlag] { 
     if (exitFlag) 
      application.quit(); 
    }); 

    exitTimer.start(); 

    std::cout << "Started! Press Enter to quit..."; 
    int ret = application.exec(); 
    f.wait(); 
    return ret; 
} 
+0

funziona bene! potresti spiegare perché hai bisogno di 'f.wait()' dopo 'exec()'? – spartawhy117

+0

È il punto di sinconizzazione esplicito in cui il thread async() si collega in modo sicuro. L'oggetto 'f' std :: future destructor non può bloccare in modo esplicito fino a quando il battistello non si unisce (che richiede l'esplorazione) – vrogach

Problemi correlati