Название: Вынос в поток Отправлено: Igors от Августа 21, 2016, 08:51 Добрый день
Читаю файлы с помощью либы которая сначала грузит/разбирает файл в память. Файлы могут быть большими (напр 100 метров) и тогда загрузка может занять десятки секунд. Callback'а (для мониторинга загрузки) не нашел. Поэтому нужно - вынести это чтение в поток - показать юзеру индикатор с бегунком ползающим туда-сюда (мол, приложение живет, просто занято) - организовать ожидание в главной нитке до конца чтения. При этом не позволять юзеру ничего нажимать (нет даже cancel), пусть ожидает конца загрузки Понятно что это можно сделать всяко-разно, но как лучше (удобнее, без слот-сигнал соплей)? Спасибо Название: Re: Вынос в поток Отправлено: kuzulis от Августа 21, 2016, 10:02 QFuture?
Название: Re: Вынос в поток Отправлено: Bepec от Августа 21, 2016, 11:18 Без сигнал-слотов в Qt, построенной на сигнал слотах... Зачем вы ставите глупые задачи?
Название: Re: Вынос в поток Отправлено: ssoft от Августа 21, 2016, 17:10 Даже если вынести чтение в отдельный поток, то все-равно потребуется обработка сигнала окончания чтения, так как блокировка главной нитки для ожидания не позволит отобразить индикатор. Интерфейс зависнет из-за такой блокировки, так как это будет имитация последовательного вызова.
А вынести чтение можно, либо реализовав чтение в run потомка QThread, либо сформировать читателя (от QObject) и перенести его в QThread. Ну или использовать QFuture. Название: Re: Вынос в поток Отправлено: Old от Августа 21, 2016, 19:37 Даже если вынести чтение в отдельный поток, то все-равно потребуется обработка сигнала окончания чтения, так как блокировка главной нитки для ожидания не позволит отобразить индикатор. Интерфейс зависнет из-за такой блокировки, так как это будет имитация последовательного вызова. Это смотря как блокировать. :)Если запустить локальный цикл обработки событий (QEventLoop), который будет завершаться при окончании загрузки, то индикатор будет спокойно работать. А вынести чтение можно, либо реализовав чтение в run потомка QThread, либо сформировать читателя (от QObject) и перенести его в QThread. Ну или использовать QFuture. Достаточно запустить функцию загрузки в отдельном потоке (std::thread) с callback-функцией, которая будет вызываться при завершении загрузки.Название: Re: Вынос в поток Отправлено: Igors от Августа 22, 2016, 14:52 Попытался сделать в общем виде, но что-то не очень выходит
Код Использование Код Соорудить QRunnable не проблема, напр Код А вот с UpdateIndicator ничего удачного не придумалось, хотелось бы избежать наследования CThreadUserProc всякий раз, просто что-то подать ему в конструктор, но не вижу как. Также QEventLoop::ExcludeUserInputEvents несовершенно - кнопка Cancel может иметься Название: Re: Вынос в поток Отправлено: Racheengel от Августа 22, 2016, 18:52 Бегунок бегает в модальном диалоге, который обновляется по таймеру, например, каждые 100 мс.
Загрузка крутится в потоке, по его окончанию QThread пошлет сигнал finished(), по которому диалог можно закрывать. По моему, это самое простое и короткое решение... Название: Re: Вынос в поток Отправлено: Igors от Августа 23, 2016, 09:35 Бегунок бегает в модальном диалоге, который обновляется по таймеру, например, каждые 100 мс. Ну по существу я так и сделал (см код предыдущего поста). Вопрос в том как лучше (удобнее, компактнее, выразительнее) это реализоватьЗагрузка крутится в потоке, по его окончанию QThread пошлет сигнал finished(), по которому диалог можно закрывать. По моему, это самое простое и короткое решение... Название: Re: Вынос в поток Отправлено: Bepec от Августа 23, 2016, 12:59 Зачем обновление по таймеру?
Насколько я помню почти 90% прогресс баров имеют режим "бесконечная загрузка", при установке минимума и максимума в 0. Так что нужен в принципе то только сигнал завершения. Название: Re: Вынос в поток Отправлено: Igors от Августа 23, 2016, 13:18 Зачем обновление по таймеру? Иначе до обновления индикатора дело не дойдет.Название: Re: Вынос в поток Отправлено: Bepec от Августа 23, 2016, 16:26 Мы в другом потоке.
ProgressBar крутится сам в основном (как я уже замечал, данный функционал есть у всех более-менее новых прогрессбаров). Крутится он в бесконечном цикле сам. Ну типа влево зелёная, вправо зелёная и так до бесконечности. Единственно что нам тогда необходимо - сообщить о завершении работы. Название: Re: Вынос в поток Отправлено: Racheengel от Августа 23, 2016, 16:58 Мы в другом потоке. ProgressBar крутится сам в основном (как я уже замечал, данный функционал есть у всех более-менее новых прогрессбаров). Крутится он в бесконечном цикле сам. Ну типа влево зелёная, вправо зелёная и так до бесконечности. Единственно что нам тогда необходимо - сообщить о завершении работы. "Сама" только земля крутится) Диалог кто-то ж должен обновлять. Если не таймер, то кто? Название: Re: Вынос в поток Отправлено: ssoft от Августа 23, 2016, 17:11 Вызов setRange ( 0, 0 ) формирует прогресс бар с анимацией "туда-сюда".
Цитировать If minimum and maximum both are set to 0, the bar shows a busy indicator instead of a percentage of steps. Название: Re: Вынос в поток Отправлено: Bepec от Августа 23, 2016, 18:04 Само крутится. Пока вы крутилку не открутите :)
Название: Re: Вынос в поток Отправлено: Igors от Августа 24, 2016, 08:15 Да, конкретно для QProgressDialog можно обойтись без таймера
Код
|