Такое ощущение, что этот вопрос задавался около ста раз ранее (например, Вот) но я еще не нашел работающего решения ..
У меня есть программа Qt5 (Linux), которая занимает некоторое время (около 2 секунд) для инициализации. Я не хочу порождать поток (по нескольким причинам), и, прежде чем инициализация будет завершена, программа все равно не будет использоваться.
В настоящее время программа запускается и показывает черное окно, пока не будет выполнена инициализация.
Я хотел бы, чтобы содержимое окна было нарисовано как можно скорее и очередь метод, который выполняет все остальное, который выполняется сразу после того, как главное окно было нарисовано.
Вот что я попробовал:
class my_window : public QMainWindow {
Q_OBJECT
explicit my_window(QWidget *parent = 0) : QMainWindow(parent) {
initializeUI();
/// UI is ready and should be drawn. initializeRest() should
/// be queued
/// tried to repaint() or update() the MainWindow and to 'force'
/// processing outstanding events - with no effect
update();
repaint();
QApplication::processEvents();
/// don't call - just queue
QMetaObject::invokeMethod(this, "initializeRest", Qt::QueuedConnection);
}
void initializeRest() {
// do stuff which takes a while
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
Но главное окно остается черным до initializeRest()
был выполнен
Как я могу сказать Qt выполнить initializeRest()
сразу после окно было построено?
Я могу подумать о запуске таймера (плохо, вводит дополнительную задержку) или обработчика события, который реагирует на какое-то событие «WindowDrawn» (плохо, сложно).
Что Qt-способ сделать это?
Обновить:
Я также пытался поставить initializeRest()
метод в main()
Функция, предложенная Мерфи:
my_window::my_window(QWidget *parent = 0) : QMainWindow(parent) {
initializeUI();
}
int main(int a_argsc, char *a_argsv[]) {
QApplication l_application(a_argsc, a_argsv);
my_window mainWindow;
mainWindow.show();
QApplication::processEvents();
mainWindow.initializeRest();
return l_application.exec();
}
С такими же результатами: ожидание внутри пары секунд initializeRest()
заставляет показать первоначально черное главное окно и быть нарисованным сразу после initializeRest()
возвратился (что кажется мне логичным, потому что цикл событий еще не запущен ..)
Примечание: это предложение не решает проблему; это оставлено здесь для полноты.
Вы можете разбить запуск на более мелкие шаги в main()
:
QApplication
пример.mainWindow
Вот). Вы можете безопасно удалить все эти перекрасить вещи после initializeUI();
из конструктора вашего примера кода.mainWindow.show()
для принудительного отображения главного окна с последующим вызовом QApplication::processEvents()
для обеспечения обработки событий краски.QApplication::exec()
,Имейте в виду, что со сложными реализациями приложений / главного окна может быть довольно сложно сделать все в правильном порядке; QSplashScreen
несомненно, будет менее утомительным решением.
Других решений пока нет …