How to handle keypress events in a Qt console application?

For example, when you press "Esc", the application ends.

+6
source share
3 answers

Qt does not handle console events, it can just read \n -termined lines from the console.

You need to use your own APIs or other libraries (curses).

+5
source

Here is a workaround for linux. Use of these messages

Capturing characters from standard input without waiting for a key press fooobar.com/questions/46788 / ...

I did it like this:

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

And then just run a new thread to read the keys:

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

* UPDATED (added restoration of terminal settings upon exit)

+5
source

If you only need to "exit", perhaps the following snippet will help (C ++ 11 and qt5 are required):

 #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; } 
+3
source

Source: https://habr.com/ru/post/898000/


All Articles