Note that there are some explanatory texts on larger screens.

plurals
  1. POQT QDialog not hiding properly when show/hide called quickly
    primarykey
    data
    text
    <p>I have a QDialog on my main thread and I have some logic that happens on a separate thread. When the logic begins, a signal is emitted connected to show() on the dialog. When the logic ends, a signal is emitted that is connected to hide() on the dialog. When the logic actually does work, the dialog is show/hide properly. If the logic does "nothing" and the signals are just emitted sequentially, the dialog doesn't always show/hide properly.</p> <p>My connections are made similar to this:</p> <pre><code>class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget* parent = 0) : Ui(new Ui::MainWindowUi), Transferer(new DataTransferer()), TransferProgress(this), TransferThread() { Ui-&gt;setupUi(); connect(&amp;Transferer, SIGNAL(Begin()), &amp;TransferProgress, SLOT(show())); connect(&amp;Transferer, SIGNAL(End()), &amp;TransferProgress, SLOT(hide())); Transferer.moveToThread(&amp;TransferThread); TransferThread.start(); Transferer.DoStuff(true); } virtual ~MainWindow() { TransferThread.quit(); TransferThread.wait(1000); delete Ui; Ui = NULL; } private: Ui::MainWindowUi* Ui; DataTransferer Transferer; TransferProgressDialog TransferProgress; QThread TransferThread; } </code></pre> <p>The logic looks similar to this:</p> <pre><code>class DataTransferer : public QObject { Q_OBJECT public: DataTransferer(QObject *parent) : QObject(parent) {} virtual ~DataTransferer() {} void DoStuff(bool dontDoStuff) { emit Start(); if (!dontDoStuff) { QThread::sleep(1); } emit End(); } } </code></pre> <p>When the DataTransferer does stuff, everything works fine. When the dialog is shown and hidden in rapid succession, I get the ghost dialog approximately every other time I call DoStuff().</p> <p>I used QThread::currentThreadId() and verified that the dialog and logic are running on separate threads.</p> <p>Why would my dialog not hide properly in this case? Should I just force my logic to always run for at least a few hundred milliseconds (that solution is bad)? Is there a way I can have my dialog make sure it's fully loaded before trying to hide itself? Should I handle these signals/slots differently?</p> <p>EDIT: I've currently resigned to just putting a QThread::sleep(1) after I emit the signal to show() the dialog. I don't like this solution, but nothing else has seemed to work. The sleep(1) allows the dialog to come all the way up before hiding it. I was also able to get this to work with QThread::msleep(10), but that still resulted in the ghost dialog about 1 in 6 tries.</p> <p>I tried using a member QMutex in the dialog logic whenever I called either show() or hide(), but this didn't work.</p> <p>I changed all cross-thread connections to use Qt::BlockingQueuedConnection and Qt::QueuedConnection and neither attempt was successful.</p> <p>I tried moving the slot connections from the dialog to the object that sets up the connections and then calling the slots directly, but that didn't prove successful either.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload