QML Почему Window.requestUpdate () не работает? - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть Qt Quick Window:

Window{
   id: mainWindow
   ...
}

Я хочу отобразить окно сообщения перед продолжительной операцией блокировки в QML:

// Set visible=true of 'messageBox' Rectangle{}
messageBox.showWaitMessage("Please wait")

// I want to show it before blocked the screen
mainWindow.requestUpdate()

// Long blocking operation:
compressFile("filepath")

Все объекты на экранедети mainWindow.


Но это не работает. Он по-прежнему не перерисовывает экран перед операцией блокировки.

Почему?

1 Ответ

1 голос
/ 04 ноября 2019

Это потому, что ваша функция, которая вызывает эти вызовы, еще не завершена, и requestUpdate(), который стоит в очереди для выполнения в цикле событий, фактически произойдет после compressFile. Это признак плохого дизайна, и лучше переместить файл compressFile в другой поток. Если многопоточность не является опцией, вы можете вызвать compressFile косвенным образом, как этот, который поместит этот вызов в очередь. Затем GUI eventloop перекрасит виджет перед выполнением слота таймера. Вам не нужно обновлять графический интерфейс вручную.

QTimer::singleShot(0, [=]() { compressFile("filepath") } );

Это возможно только для Qt5.4 и выше из-за QTBUG-26406 . Если вы используете более низкую версию Qt, вы можете сделать то же самое, например:

    QTimer *timer = new QTimer(this);
    timer->setSingleShot(true);
    connect(timer, &QTimer::timeout, [=]() {
       compressFile("filepath");
       timer->deleteLater();
    } );
    timer->start(0);
...