Как я могу закрыть диалог, из другого потока? Qt
Я хочу обработать мою кнопку следующим образом:
- Изменить текст на этикетке (что-то вроде "Пожалуйста, подождите...")
- Скачать некоторые данные из базы данных
- Когда загрузка будет завершена, закройте диалоговое окно, где находится эта кнопка.
Когда я делаю это:
void LoadingDialog::on_pushButton_clicked()
{
m_ui->labelStatus->setText("Pobieranie wysyłek...");
if(m_methodToDo == MethodToDo::LoadShipment)
{
if(DataManager::getManager()->loadShipments())
{
this->close();
}
}
}
метка не изменила текст, имеет задержку в несколько секунд (загружает несколько k записей), и диалог закрывается.
Когда я пытаюсь это:
void LoadingDialog::changeStatus(QString status)
{
m_ui->labelStatus->setText(status);
}
bool LoadingDialog::load()
{
if(m_methodToDo == MethodToDo::LoadShipment)
{
if(DataManager::getManager()->loadShipments())
{
this->close();
}
}
}
void LoadingDialog::on_pushButton_clicked()
{
QFuture<void> future3 = QtConcurrent::run([=]() {
changeStatus("Pobieranie wysyłek..."); // "Downloading.."
});
QFuture<void> future = QtConcurrent::run([=]() {
load();
});
}
у метки есть измененный текст - все в порядке, задержка в несколько секунд - это нормально, но диалог не закрыт, и мое приложение выдает исключение:
Cannot send events to objects owned by a different thread. Current thread 229b1178. Receiver 'Dialog' (of type 'LoadingDialog') was created in thread 18b00590
Любое предложение?
1 ответ
Решение
Во-первых, changeStatus не блокирует, поэтому не запускайте его в другом потоке. С другой стороны, если вы хотите вызвать слот из другого потока, вы можете использовать QMetaObject::invokeMethod()
:
bool LoadingDialog::load()
{
if(m_methodToDo == MethodToDo::LoadShipment)
if(DataManager::getManager()->loadShipments())
QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
}
void LoadingDialog::on_pushButton_clicked()
{
changeStatus("Pobieranie wysyłek..."); // "Downloading.."
QFuture<void> future = QtConcurrent::run([=]() {
load();
});
}