Synchronous custom input dialog
-
Hello,
Using Qt 4.8 on the raspberry pi, I'd like to figure out if it's possible to open a dialog, wait for a callback, and return the value, all synchronously, in-line?
I probably didn't articulate that right, but I want to have a dialog that can behave like this:
@/////////////////////////////////////////////
// Usage (Main window)
/////////////////////////////////////////////void MyWindow::onButtonClicked()
{
string input = MyDialog::GetInput();
qDebug("got: %s", input.c_str());
}/////////////////////////////////////////////
// MyDialog
/////////////////////////////////////////////string MyDialog::Value = "";
bool MyDialog::Finished = false;void Callback(string val)
{
MyDialog::Value = val;
MyDialog::Finished = true;
}string MyDialog::GetInput()
{
MyDialog* dialog = new MyDialog();
dialog->show();
dialog->Callback = &Callback;
int i=0;
// Wait for callback
while (MyDialog::Finished == false)
i = 0;
return MyDialog::Value;
}@MyDialog has a text field and an on-screen keyboard I made, and when you click finished, dialog.Callback is called with the value entered. I have this part working, but the callback is async. I tried wrapping the contents of the MyDialog::GetInput() above in a QThread, but I still halt the application with my essentially infinite while loop, since I never see the dialog and can't click finish to trigger the callback
What I'd like to do is get that value, synchronously without stopping the gui thread, but I'm calling it from the gui thread's onClick method. Is this feasible? Does that makes sense?
In short, I'd like this:
@void MyWindow::onButtonClicked()
{
string input = MyDialog::GetInput();
// Open dialog, get input, return value
qDebug("got: %s", input.c_str());
}@instead of:
@void Callback(string val)
{
qDebug("got: %s", val.c_str());
}void MyWindow::onButtonClicked()
{
MyDialog* dialog = new MyDialog();
dialog->show();
dialog->Callback = &Callback;
}@Hope this wasn't too confusing!
Thanks for any help!! -
I tried to read and understand your requirement. I was not able to connect all dots to answer correctly.
Thought#1 - Is it not as simple as this ?@
QFileDialog dialog;
QPushButton button("pthinks.com");
button.show();
QObject::connect(&button,SIGNAL(clicked()),&dialog,SLOT(exec()));
@
Thought#2
It also gave me a impression that you are trying to do two tasks at same time in single UI thread. Is that true ? If that is the case you UI thread can do one task at a time. -
Hi, phil.harlow.
Using the QInputDialog class, it can be as simple as:
@bool ok;
QString text = QInputDialog::getText(this, tr("Title"), tr("Label:"), QLineEdit::Normal, tr("InitialText"), &ok);
if(ok) qDebug("Input was: %s", qPrintable(text));@And if you use a custom Dialog class, derived from QDialog, you can do:
@MyDialog dialog;
dialog.exec(); /* this will block until dialog is closed !!! */
QString userInput = dialog.getValue();@Note that only the QDialog::exec() function will block until the user closes the dialog. But internally, the dialog will be running its own event loop - which means that the GUI remains perfectly responsive while the dialog is showing!
Also, my example above assumes your custom dialog has some getter function, like getValue(), which can be used to read the user's input, after the dialog has been closed. Adding this is trivial. No signals or callbacks needed here.
--
bq. int QDialog::exec()
Shows the dialog as a modal dialog, blocking until the user closes it. -
[quote author="Dheerendra" date="1405166332"]I tried to read and understand your requirement. I was not able to connect all dots to answer correctly. [/quote]
Sorry Dheerendra, I had trouble articulating what I needed. MuldeR has exactly what I was looking for. Thanks!
[quote author="MuldeR" date="1405172321"]And if you use a custom Dialog class, derived from QDialog, you can do:
@MyDialog dialog;
dialog.exec(); /* this will block until dialog is closed !!! */
QString userInput = dialog.getValue();@Note that only the QDialog::exec() function will block until the user closes the dialog. But internally, the dialog will be running its own event loop - which means that the GUI remains perfectly responsive while the dialog is showing!
bq. int QDialog::exec()
Shows the dialog as a modal dialog, blocking until the user closes it.[/quote]Thank you MuldeR!! That's exactly what I needed! I forgot to mention that MyDialog did extend QDialog, so that was exactly the solution I needed. I'm not sure how I missed it in the documentation, but thank you for your help!