Russian Qt Forum

Qt => Общие вопросы => Тема начата: fulkabaster от Март 07, 2009, 16:36



Название: Поток QThread из главного окна.
Отправлено: fulkabaster от Март 07, 2009, 16:36
Читал Бланшет, но там для примеров приводятся либо самые простые, либо специфические случаи. Поэтому прошу подсказки у знатоков.

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

У приложения есть функция, считывающая кусок в файле заданной длины. Нужно, чтобы второй поток просто в цикле выполнял эту функцию. Можно ли сделать это примерно так: в главном приложении создается объект подкласса QThread с перегруженной функцией run(), в конструкторе потока передавать ему ссылку на QMainWindow (т.е. this), а в функции run в потоке вызывать через этот указатель ту самую функцию считывания? Или есть более правильные приёмы?


Название: Re: Поток QThread из главного окна.
Отправлено: uriel от Март 07, 2009, 16:49
Можно просто вызывать функцию считывания данных внутри run() в цикле, пока не считается весь файл. На каждой итерации можно выбрасывать сигнал, на который главное окно реагировало бы обновлением прогрессбара или как-нибудь так.


Название: Re: Поток QThread из главного окна.
Отправлено: pastor от Март 07, 2009, 18:43
...в конструкторе потока передавать ему ссылку на QMainWindow (т.е. this), а в функции run в потоке вызывать через этот указатель ту самую функцию считывания?

Нет, так делать нельзя. Из другого потока нельзя обращаться в GUI напрямую. Читайте данные в run() вашего потока и передавайте из при помощи технологии "сигнал-слот" или при помощи custom event.


Название: Re: Поток QThread из главного окна.
Отправлено: BRE от Март 07, 2009, 19:12
...в конструкторе потока передавать ему ссылку на QMainWindow (т.е. this), а в функции run в потоке вызывать через этот указатель ту самую функцию считывания?

Нет, так делать нельзя. Из другого потока нельзя обращаться в GUI напрямую. Читайте данные в run() вашего потока и передавайте из при помощи технологии "сигнал-слот" или при помощи custom event.
Я думаю человек имеет ввиду следующую конструкцию:
Код
C++ (Qt)
void MainWindow::readChunk()
{
   file.read(...);
}
 
и дергать эту функцию из второго потока. В принципе, если не использовать в ней функции связанные с GUI, такое возможно.
Только, с точки зрения архитектуры системы, мне не понятно на каком основании объект главного окна будет что-то читать? Главное окно должно рисовать и обрабатывать действия пользователя.
Может сделать отдельный класс-контейнер, который под защитой мутексов, будет читать данные, предоставлять прочитанные данные и делать все с этим связанное?


Название: Re: Поток QThread из главного окна.
Отправлено: Steven_Orko от Март 10, 2009, 09:05
Можно просто вызывать функцию считывания данных внутри run() в цикле, пока не считается весь файл. На каждой итерации можно выбрасывать сигнал, на который главное окно реагировало бы обновлением прогрессбара или как-нибудь так.
+1 Имхо, лучший из вариантов, если обработка считанных данных по каким-либо причинам будет происходить в основном GUI-thread.


Название: Re: Поток QThread из главного окна.
Отправлено: Winstrol от Март 10, 2009, 10:56
Забудьте вы о потоках, мьютексах и прочих низкоуровневых вещах. Они предназначены не для валового юзера.  В Qt появились средства для task level parallelism. Смотреть примеры и хелп по QFuture, QFutureWatcher, QtConcurrent::run.