2009-11-02 3 views
1

Я хочу добиться загрузки файла в отдельном потоке и сохранить этот файл , но я не смог найти подходящий способ для достижения этого без злой задержки (довольно частая загрузка небольших файлы, поэтому сигнальные + слоты слишком медленные). То, что я хочу добиться: (псевдокод)Синхронизация файла C++/Qt

request file; 
wait for download finishing, timeout or error; 
save downloaded file; 

Я предпочел бы пример с QNetworkAccessManager, если это возможно. Спасибо за любой типп.

Редактировать: Чтобы быть ясным, я хочу, чтобы сигнал и слоты не были из-за дизайна, а также из-за отсутствия скорости.

Редактировать2: Эта загрузка относится только к файлу загрузки в части синхронизации, потоки не представляют проблемы. Проблема в том, что QT не обеспечивает api для этого, и я не увлекаюсь ожиданием hotspinning.

Edit3: Пример кода, как это должно работать, но это не так:

QNetworkAccessManager net; 
QNetworkReply *re (net.get(QNetworkRequest(QUrl(Qstring("www.blah.org/key"))))); 
if (re->waitForReadyRead(-1)) //! @bug this does not work as supposed, waitForRead returns false and returns INSTANTLY!! 
    qDebug() << "ReadyRead yeha!!!"; 
if (re->error()) { 
    qDebug() << "Can't download" << re->url().toString() 
      << ":" << re->errorString(); 
} else { 
    img->load(re->readAll()); 
    qDebug() << "Savin IMG"; 
} 
delete re; 
+0

Кажется, что без локального цикла событий ваш «ре» даже не знает, что он закончен. Я столкнулся с подобной проблемой. Постскриптум Не удаляйте напрямую QNetworkReply, используйте «deleteLater». – QtRoS

ответ

1

мне нужно было что-то подобное, но по разным причинам. Так как QHttp и QNetworkAccessManager являются как асинхронными, тем больше вы можете использовать отдельный цикл событий, полный пример на основе QHttp можно найти here. Это не должно быть слишком сложно изменить для QNetworkAccessManager.

Следует упомянуть, что ваше впечатление, что сигналы/слоты являются «медленными», вероятно, неверно. Вы действительно профилировали свой код, чтобы определить это?

Независимо от того, какой штраф вы платите за сигналы/слоты, это, вероятно, незначительно, если посмотреть на количество времени, которое требуется загрузить одному файлу. Более того, это очень «не Qt», чтобы так поступать. Эти классы были разработаны именно по этой причине.

В конце дня если вы действительно страдаете от сигналов/слотов (что опять-таки, сомнительно), я бы рекомендовал не использовать Qt для этой конкретной задачи, может быть ясно, старые гнезда C являются лучшей идеей (или тонкую оболочку вокруг них, чтобы сохранить обработку ошибок, которая может потребовать дополнительной работы).

+0

Ну, я надеялся не использовать exec() в параллельном потоке. У вас есть идея :-D спасибо – drahnr

+0

ОК после 3 часов поиска Я наткнулся на это: http://wiki.qtcentre.org/index.php?title=Keeping_the_GUI_Responsive и он предлагает то же самое, что вы мне предложили , и я сделал это так, и он работает. Спасибо. Вы решили это :-) – drahnr

0

Доступ к сети с синхронизацией - это плохая идея, потому что это создает плохую работу пользовательского интерфейса. Кроме того, что вы считаете ошибкой, это не ошибка. Это просто неправильно документировано.

+0

Синхронизация их идеально подходит для тестирования инструментов, модульных тестов и даже логики сервера/что-то, что просто не дает ответа в режиме реального времени. –

Смежные вопросы