0

I know that it's bad to run any kind of GUI widget from within a separate thread. For just messages, this can be overcome with signals to the main thread. But what if the thread needs a user input, how can the answer be signaled back to the thread and how can that thread wait for that answer?

My particular case is an application that uses sftp from libssh. During connection and authentication, the user may need to answer one or more questions. But for performance reasons, all the SSH/SFTP stuff must be running in a separate thread.

Eitan T
  • 32,660
  • 14
  • 72
  • 109
Pat
  • 1,726
  • 11
  • 18
  • Any reason you can't get the user's credentials before starting the thread? – eduffy Jun 24 '12 at 14:59
  • For simple password authentication that would be sufficient, but SSH authentication may be interactive, meaning the server asks you questions, you supply answers and server may ask new questions again, ...etc. – Pat Jun 24 '12 at 15:18

1 Answers1

1

It is not possible to use GUI classes in non-GUI threads at all. What you can do is use signals and slots to exchange information from one thread to another. Send a signal from your worker thread and wait on a semaphore, like QWaitCondition. Send a message back with the answer.

In your case you could also use Qt::BlockingQueuedConnection as connection type to stop your worker thread until the user has entered data. QInputDialog also waits until the user has finished entering data.

Eitan T
  • 32,660
  • 14
  • 72
  • 109
Luca Carlon
  • 9,546
  • 13
  • 59
  • 91
  • If you send a signal from the worker thread, why would you need to wait on a semaphore?! A QObject in the worker thread can receive the reply in a slot of its own. The appropriate connection type will be used by Qt by default. – Kuba hasn't forgotten Monica Jun 25 '12 at 01:57
  • The question asked clearly how the worker thread could "wait" for the answer. So I assumed that was the point. If there is no need to "manually" stopping the procedure, then again, I said it in my second sentence, signals and slots can be used to exchange information: emit a message with the reply. But the asker seemed to know this already, so I might have misunderstood the question. – Luca Carlon Jun 25 '12 at 06:13
  • The explicit wait is wholly unnecessary. Waiting on a mutex is what the event loop does already. A QObject, whether moved to a non-GUI thread or not, waits most of the time: all the time it doesn't execute any code, in fact. "Waiting" on an answer is inherent. The answer simply comes in as a signal that's hooked up to a slot in a QObject. Using GUI classes in non-gui threads is done simply by sending signals to widgets. You can send a made-up signal from a single line of code, e.g.: to set text on a QLabel, you can do `QMetaObject::invokeMethod(label, "setText", Q_ARG(QString, "foo"));` – Kuba hasn't forgotten Monica Jun 25 '12 at 10:53