Qt Gui не обновляется из-за проблем с потоками

Я использую стороннюю библиотеку, которая для динамической загрузки нескольких библиотек занимает 60-90 секунд. Это неудачный выбор дизайна, но я не могу изменить, кто создал их код.

Я пытаюсь использовать QSplashScreen, чтобы хотя бы сказать пользователю подождать, пока я делаю эту одноразовую загрузку в фоновом режиме. Проблема в том, что заставка не красит. Я могу видеть окно неокрашенного пространства, пока загружается библиотека. Я могу видеть заставку потом, прежде чем закрыть его.

Я смотрел на похожие вопросы (например, Qt Splash Screen не отображается) но, кажется, ничто не решает мою проблему. Я попытался загрузить пустой QPixmap и просто дать ему сплошной цвет. Это тоже не появляется.

QApplication a(argc, argv);
QPixmap pxl("icon.bmp");
QSplashScreen qss(pxl);
qss.show();
qss.showMessage(QString::fromStdString("Please wait... Loading"));
a.processEvents();

MainWindow w;
//thread is blocked
w.preLoad();//this is where the lengthy process takes place
w.show();

qss.finish(&w);

Я хотел бы убедиться, что он хотя бы разок закрасит, прежде чем начать процесс загрузки.

————————РЕДАКТИРОВАТЬ——————————-

Позвольте мне повторить, что вызов preLoad БЛОКИРУЕТ поток. Это не вариант. Я пробовал отдельный поток для этого процесса. Я попытался с отдельной темой для заставки (включение и последующее завершение, когда другой поток завершен). Я попытался использовать семафор между двумя потоками для достижения этой цели, и хотя все работает (включая заставку), для загрузки требуется 200-800 секунд. Это просто не приемлемо. Таким образом, я хотел бы посмотреть, есть ли что-то подобное с этой точки зрения.

————————-Окончательное решение———————————

Благодаря комментариям, приведенным ниже, я узнал, что Qt имеет свою собственную функциональность потоков. Кажется, все проблемы, которые я видел, были вызваны взаимодействием std :: thread и собственной реализации Qt.

У меня есть частичное решение, которое работает. Это не так аккуратно, как могло бы быть, но я хотел включить его в ветку вопросов.

//in the main method code described above
MainWindow w;
w.preLoad();
while(w.IsLoading())
{
//waiting on semaphore signaling loading is complete
//this part could probably be done better with QThread
//and signals, but it is a quick fix for now
std::this_thread::sleepfor(std::chrono::milliseconds(500));
a.processEvents();
}
w.show();

qss.finish(&w);//In the MainWindow class
void MainWindow::preLoad()
{
loading=true;//semaphore to stall main thread
QFuture<void> future = QtConcurrent::run(this, &MainWindow::LongMethod);
}

void MainWindow::LongMethod()
{
thirdPartyLibrary.impossibleCall();
loading=false;//this handles my semaphore
}

0

Решение

Каждый GUI выполняется в бесконечном цикле, поэтому Qt также использует его, но задачи блокировки генерируют, что цикл выполняется неправильно, показывая неадекватное поведение, подобное тому, которое вы наблюдаете.

Если кто-то хочет выполнить блокирующие задачи, рекомендуется выполнить его в другом потоке, поскольку Qt предоставляет несколько возможностей:

Я рекомендую следующее ссылка на сайт для вас, чтобы выбрать правильный вариант для вашего случая.

Если вы хотите обновить представление GUI информацией, сгенерированной в другом потоке, рекомендуется использовать сигналы и слоты или использовать QtConcurrent.

Нить GUI и рабочая нить

Как уже упоминалось, каждая программа имеет один поток при запуске. это
поток называется «основным потоком» (также известный как «поток GUI» в
Приложения Qt). Графический интерфейс Qt должен работать в этом потоке. Все виджеты и
несколько связанных классов, например QPixmap, не работают во вторичном
потоки. Вторичный поток обычно называют «рабочий»
поток «, потому что он используется для разгрузки обработки работы с основного
нить.

Другой способ состоит в том, чтобы принудительно обновить графический интерфейс для этого мы можем использовать qApp-> processEvents ().

Рекомендации:

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]