Russian Qt Forum

Qt => Общие вопросы => Тема начата: IGHOR от Апрель 02, 2010, 02:33



Название: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 02, 2010, 02:33
Пишу QThread в котором идет копирование файлов внутри функции run() и он передает по сигналу в прогресбар значения.
Поискав на форуме решение, понял что GUI можно создавать только в GUI потоке и общаться по сигналам и слотам и это работает безупречно.
Но мне нужно посредине обработки QDirIterator в функции run() спросить пользователя (Заменить,Пропустить,Отмена) через QMessageBox или любой виджет.
И незнаю как в таком случае использовать слоты и сигналы.
Подскажите что искать или как можно это правильно реализовать?


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: voronElf от Апрель 02, 2010, 05:19
2 сигнала - один на запуск диалога, другой обратно в тред с результатом работы диалога. в промежутке между сигналами тред ждать должен.

ПС: треды не писал, можт какие подводные камешки есть у подхода ...


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: SASA от Апрель 02, 2010, 10:12
На сколько я понял из моего общения со статическими функциями QMessageBox им вообще пофиг от куда запускаться.


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: voronElf от Апрель 02, 2010, 10:15
даже из другого треда ?


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: Igors от Апрель 02, 2010, 11:39
Но мне нужно посредине обработки QDirIterator в функции run() спросить пользователя (Заменить,Пропустить,Отмена) через QMessageBox или любой виджет.
Нитка читающая файлы должна послать сигнал в главную. Коннект для этого сигнала должен быть создан с флагом BlockedQueuedConnection - вызывающий ждет ответа (пока диалог закроется). В главной - просто QMessageBox используя переданные слоту данные


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 02, 2010, 11:49
SASA, нет не пофиг, из треда нормально не запускается.
Igors, передать меседжбоксу с флагом BlockedQueuedConnection для запуска вопроса это ясно, а как возвращать назад результат ответа в точку вызова?
voronElf, и как ждать посредине обработки QDirIterator?


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: Igors от Апрель 02, 2010, 12:26
Igors, передать меседжбоксу с флагом BlockedQueuedConnection для запуска вопроса это ясно, а как возвращать назад результат ответа в точку вызова?
В параметрах сигнала - указатель или ссылка. Если "Blocked.." то все происходит синхронно/последовательно, можно читать/писать без блокировок


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 02, 2010, 17:40
Igors, на что именно указатель передавать в сигнале?
можно пример на пару строк?


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: SimpleSunny от Апрель 02, 2010, 19:03
Если я правильно понял, то указатель на результат.

Код
C++ (Qt)
int result = 0;
emit userQuestion(&result);
switch (result)
{
...
}


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: Igors от Апрель 02, 2010, 19:07
Igors, на что именно указатель передавать в сигнале?
можно пример на пару строк?
Можно на результат, на любую структуру - лишь бы существовало на момент вызова сигнала с "blocked" и было удалено после возврата из сигнала.


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 02, 2010, 19:58
SimpleSunny, Igors спасибо за помощь


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: SASA от Апрель 03, 2010, 14:50
SASA, нет не пофиг, из треда нормально не запускается.
Да, действительно не пофиг. Значит показалось. :'(


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 04, 2010, 07:37
Делаю копирование файла так:
Код:
while(retry==1)
{
QFile::copy(copyFrom,copyTo);
if(!QFile::exists(copyTo))
  emit MessageBoxRetry(text,&retry);
else break;
}

Если файл не смог копироваться то выскакивает диалог с вопросом как и должно быть,
но если нажать Retry тогда после проверки диалог должен еще раз появиться но после ретрая в ответ получаю ошибку:
Код:
inline bool QObjectPrivate::isSignalConnected(uint signal_index) const
{
    return signal_index >= sizeof(connectedSignals) * 8
        || qt_signal_spy_callback_set.signal_begin_callback
        || qt_signal_spy_callback_set.signal_end_callback
        || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f)));
            // в этой последней строке в файле qobject_p.h
}

Что дальше делать?

Ну а если файл копировался естественно окно диалога не появляется. Но оно всегда появляется, все пути в дебагере верны и файл существует, почему QFile::copy() не работает в треде?


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: SimpleSunny от Апрель 04, 2010, 08:19
А какой текст ошибки?

Не совсем понятно, файлы не копируются или копируются, но диалог все равно появляется? Если не копируются, то какую ошибку возвращает QFile?
QFile f(fileName).copy(newName); f.error();


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 04, 2010, 18:00
SimpleSunny, все работает, я случайно путь перепутал, а проблема с повторным вызовом того же сигнала осталась


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: SimpleSunny от Апрель 04, 2010, 18:50
Компилируемый пример, наверное, помог бы в поиске ошибки.


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 04, 2010, 20:36
Вот компилированный пример


Название: Re: Вопрос пользователю изнутри QThread
Отправлено: IGHOR от Апрель 05, 2010, 05:34
Я догадался в чем проблема, просто надо было:
Код:
QMessageBox msgBox;
msgBox.setAttribute(Qt::WA_QuitOnClose,false);
и все работает без ошибок