2011-09-25 40 views

回答

5

Qt不处理控制台事件,它只能从控制台读取\n终止行。

您需要使用本机API或其他库(curses)。

+0

感谢您的帮助 –

5

这是一个针对linux的解决方法。使用这些帖子

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

我做了这样的:

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); 
    } 
} 

然后才开始新的线程来读取键:

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

*更新(添加恢复终端上退出设置)

3

如果你只需要“退出”也许下面的代码片段将帮助(C + +11和qt5需要):

#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

运作良好!你能解释为什么'exec()'后面需要'f.wait()'? – spartawhy117

+0

这是async()线程安全连接的显式同步点。 'f'对象std :: future析构函数可能不会显式阻塞,直到踩到连接(需要探索) – vrogach

相关问题