2

Im making a console application where Im getting user input with std::getline() (in a while loop). Im also using QextSerialPort (inherits QIODevice). Thus I need an event loop so I'm using QCoreApplication and calling a.exec().

The problem is getline() blocks event loop and, while it's blocked, I can't receive anything from serial port. I tried to use

QCoreApplication::processEvents() in the while(1){getline()} loop, but found that's not a good solution. Then, I tried to call

QCoreApplication::processEvents() in a QThread but it didn't work.

Here's the code Im using:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Base *base = new Base();
    Commander *commander = new Commander(base);

    QObject::connect(commander, SIGNAL(end()), &a, SLOT(quit()));
    QTimer::singleShot(0, commander, SLOT(run()));

    return a.exec();
}

void Commander::askToConnect()
{
    if(base->connect() == false){
        cout << "Failed to open port." << endl;
    }
}

void Commander::run{
    string inputline;

    askToConnect();

    while(1){
       QCoreApplication::processEvents();  // ???

       cout << endl << "> ";
       getline(cin, inputline);

       // ...
    }
}

How can I have a getline() (or similar method) without blocking event loop?

1 Answer 1

5

Yes, i got similar experiences with the ProcessEvent() method called from the main thread. The problem is that it's just put on top of the current call stack and that can have other nasty side effects like endless calling depth or re-entrance problems.

I would just add a few threads to your application to create a clean solution. Since getLine() belongs to the (console) user interface, I would keep it in the main thread and move the networking code into an extra thread but other solutions are also possible (spawning threads for all kinds of interactions and just maintaining them from the main thread).

Sign up to request clarification or add additional context in comments.

2 Comments

Moving communication code to a separate thread is mostly a good idea. If you let it communicate with the main thread only via signal/slot connections you get thread safety for free.
I forgot to mention: Im using readyRead signal from QextSerialPort to receive data asyncronously. When I receive data from serial port I print it on terminal with qDebug(). However, once event loop is blocked, it just prints after I type something and press enter (getline()). And that's just because Im calling QCoreApplication::processEvents() in the while loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.