Skip to content

Instantly share code, notes, and snippets.

@gjorquera
Last active February 4, 2024 12:44
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save gjorquera/2576569 to your computer and use it in GitHub Desktop.
Save gjorquera/2576569 to your computer and use it in GitHub Desktop.
Qt way to read from stdin.
#include <iostream>
#include "console.hpp"
void Console::run()
{
std::cout << "First message" << std::endl;
std::cout << "> " << std::flush;
connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readCommand()));
}
void Console::readCommand()
{
std::string line;
std::getline(std::cin, line);
if (std::cin.eof() || line == "quit") {
std::cout << "Good bye!" << std::endl;
emit quit();
} else {
std::cout << "Echo: " << line << std::endl;
std::cout << "> " << std::flush;
}
}
#pragma once
#include <QObject>
#include <QSocketNotifier>
#include <iostream>
class Console : public QObject
{
Q_OBJECT;
public:
Console();
void run();
signals:
void quit();
private:
QSocketNotifier *m_notifier;
private slots:
void readCommand();
};
inline Console::Console()
{
m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this);
}
#include "console.hpp"
#include <QCoreApplication>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
Console console;
console.run();
QObject::connect(&console, SIGNAL(quit()), &app, SLOT(quit()));
return app.exec();
}
@rmflow
Copy link

rmflow commented Jul 23, 2014

jeez, man, did you even compile this?

@bugrazoid
Copy link

Just add stdio.h in console.h and change *QSocketNotifier m_notifier to *QSocketNotifier notifier. Work well! Thanks!

@gjorquera
Copy link
Author

Wow, it's been years since I uploaded this. I don't even remember when or why I wrote it.
Anyways, I just updated it. Thanks @bugrazoid.

@AlexandreGerault
Copy link

Wow, I think it is exactly what i was wondering for! Thanks a lot man

@adam-ce
Copy link

adam-ce commented Feb 4, 2017

it's quite elegant : )

There is similar code on SO: http://stackoverflow.com/questions/6878507/using-qsocketnotifier-to-select-on-a-char-device/7389622#7389622
I'm not sure which came first or whether they are even related, but this one contains two important fixes over SO:
use std::getline(std::cin, line); in readCommand (QTextStreams buffers confuse stdin notifier) and having the socket as a child (graceful moving to a new thread and stdin is not threadsafe).

I edited the SO answer and the edit is pending peer reviewing.

@AlexandreGerault
Copy link

Hey.
I'm just having trouble with your code on a Windows setup... I can't write in the console. Is someone having any idea about it?
Thanks a lot!

@spartawhy117
Copy link

@Alexan14 i have the same problem, have you solved it?

@hao-lee
Copy link

hao-lee commented Dec 6, 2017

Awesome! Very useful! It works well on Linux with Qt 5.6.

@olned
Copy link

olned commented Dec 23, 2017

Thanks!
@spartawhy117, to support Windows take a look at this example.
I just added a few lines to the proposed code:

#ifdef Q_OS_WIN
#include <QWinEventNotifier>
#include <windows.h>
#else
#include <QSocketNotifier>
#endif
...
#ifdef Q_OS_WIN
    QWinEventNotifier *m_notifier;
#else
    QSocketNotifier *m_notifier;
#endif
...
#ifdef Q_OS_WIN
    m_notifier = new QWinEventNotifier(GetStdHandle(STD_INPUT_HANDLE));
    connect(m_notifier, &QWinEventNotifier::activated
#else
    m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this);
    connect(m_notifier, &QSocketNotifier::activated
#endif
        , this, &Console::readCommand);

@sequency
Copy link

sequency commented Mar 9, 2018

Thanks, exact what I needed.
Just one thing I had to change, in console.hpp line 9:
Q_OBJECT <- no semicolon goes here
Using Qt 5.10 on openSuSE 42.3 and raspbian jessie

@juangburgos
Copy link

Hi guys,

I updated this to Qt5 and C++11 and put it in a repo so it can be used as a git submodule:

You can find it here.

Cheers,

@mayankgowda
Copy link

Thanks a lot man. It was exactly what i was looking for.

@AndreiCherniaev
Copy link

There is another example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment