У меня есть QDialog в моем основном потоке, и у меня есть логика, которая происходит в отдельном потоке. Когда начинается логика, в диалоговом окне вызывается сигнал show(). Когда логика заканчивается, выдается сигнал, который подключен к hide() в диалоговом окне. Когда логика действительно работает, диалог отображается/скрывается должным образом. Если логика «ничего» и сигналы просто испускаются последовательно, диалог не всегда отображается/скрываться должным образом.QT QDialog не скрывается должным образом при быстром вызове/скрытии
Мои соединения выполнены подобным образом:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0) :
Ui(new Ui::MainWindowUi),
Transferer(new DataTransferer()),
TransferProgress(this),
TransferThread()
{
Ui->setupUi();
connect(&Transferer, SIGNAL(Begin()), &TransferProgress, SLOT(show()));
connect(&Transferer, SIGNAL(End()), &TransferProgress, SLOT(hide()));
Transferer.moveToThread(&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;
}
Логика выглядит примерно так:
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();
}
}
Когда DataTransferer делает вещи, все работает отлично. Когда диалог отображается и скрывается в быстрой последовательности, я получаю диалог призрака примерно каждый раз, когда я вызываю DoStuff().
Я использовал QThread :: currentThreadId() и проверил, что диалог и логика работают на отдельных потоках.
Почему мой диалог не спрятался должным образом в этом случае? Должен ли я просто заставить мою логику всегда работать в течение по крайней мере нескольких сотен миллисекунд (это решение плохо)? Есть ли способ, которым мой диалог может быть полностью загружен, прежде чем пытаться скрыть себя? Должен ли я обрабатывать эти сигналы/слоты по-разному?
EDIT: Я в настоящее время смирился с тем, что просто вставил QThread :: sleep (1) после того, как я издал сигнал, чтобы показать() диалог. Мне не нравится это решение, но больше ничего не работает. Сон (1) позволяет диалогу пройти весь путь, прежде чем скрывать его. Я также смог заставить это работать с QThread :: msleep (10), но это все равно привело к диалогу призрака примерно 1 из 6 попыток.
Я попытался использовать член QMutex в логике диалога всякий раз, когда я вызывал либо show(), либо hide(), но это не сработало.
Я изменил все кросс-потоковые подключения, чтобы использовать Qt :: BlockingQueuedConnection и Qt :: QueuedConnection, и ни одна попытка не была успешной.
Я попытался переместить соединения слота из диалогового окна в объект, который устанавливает соединения, а затем вызывает слоты напрямую, но это тоже не оказалось успешным.
Используется QMutex для установки блокировки функций Show()/Hide() для блокировки/разблокировки до и после действий; нет успеха. Я также прочитал связанное решение и попытался использовать все типы логических подключений, и проблема все еще сохраняется. –