Название: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 04, 2010, 14:59 хотел сделать, чтобы если перерисовка некоего объекта требует времени больше полсекунды, отображались песочные часы, вроде все просто
Код: void MainWindow::slWaitCursor() cursorchanged всадил на всякий случай, поскольку не написано, что restoreOverrideCursor() ничего не делает, если курсор не перегружался шаманство с реконнектом слотов сделал, поскольку timer->singleShot стреляет всегда, независимо от способа и времени исчезновения или остановки таймера - то есть, если сделать stop до истечения времени, сигнал тоже будет послан но... не работает, почему-то таймер не запускается, поскольку явно видно, что никогда не вызывается slNull() и не меняется курсор, вообще никогда но! стоит убрать строку timer.stop(); - таймер начинает удивительным образом работать, сигнал в slNull сыпется каждые 500 мсек :o large_object->Redraw(); не содержит ни таймеров, ни параллельных нитей, ничего, кроме много-много рисования на QGraphicsScene (причем именно держит свой код обработки объекта, который там выполняется), либо наоборот, мало-мало (тогда курсор менять не надо), но гарантированно - даже когда рисуется все пару секунд, никакие сигналы от таймера не идут, смотрел в отладчике - перед вторым connect в таких случаях явное зависание, но контрольная точка внутри slWaitCursor() не срабатывает (если убрать timer.stop(); то срабатывает) думал, может очередь сообщений где-то блокируется, но вызов a->processEvents(); (a это есессно указатель на QApplication) не помогает тупик... можно подумать и сделать часы как-то иначе, но вроде тут все должно работать Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 04, 2010, 15:44 методом тыка выяснил, что
- таймер таки запускается, после отрисовки он остается активен, и останавливается соответствующим stop() - независимо от заданного времени таймера, он не срабатывает по истечении заданного времени, поскольку stop() выполняется и после 2х секунд рисования, то, что таймер работает, показывает проверка isActive() НО! при этом таймером не генерится сигнал, и слот slNull() не вызывается, пробовал с разными типами соединений - не имеет значения - при этом сигнал почему-то генерится, если убрать остановку таймера... ??? - при длительной перерисовке курсор мигает я баг нашел? Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: BRE от Июнь 04, 2010, 15:54 Код
В методе Redraw я думаю есть большой цикл, в котором и рисуются все необходимые объекты. Добавь в него processEvents, для того что-бы цикл обработки событий крутился. И думаю сигналы заработают. ;) Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 05, 2010, 00:06 ооо... там сложно рисуется... надо пробовать, но как-то странно выглядит это все :(
тем более, что в Redraw используются вызовы Qt для рисования отдельных объектов, по идее оно должно разобраться с событиями и если затык в том, что сигнал от таймера во время Redraw не приходит, то тогда почему он не приходит и после окончания Redraw?... Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 07, 2010, 08:58 хех... попробовал добавить вызов processEvents() внутрь Redraw(), причем не на каждый элемент, а только перед некими "крупными" действиями, результат удручающий... оно то заработало, но отрисовка замедлилась в несколько раз, и что самое ужасное, стало видно, как сцена рисуется, чего собственно и следовало ожидать >:(
то есть, надо вычленить, и разрешить только событие таймера, чтобы processEvents() разрешало прохождение только его событий, либо хотя бы запретить прохождение событий при рисовании - а такой возможности нет... :( есть только два флага QEventLoop::ExcludeUserInputEvents и QEventLoop::ExcludeSocketNotifiers, оба не подходят чтобы гарантированно работало, наверно надо бы второй тред запустить, но небось же нельзя из второго треда просто обратиться к методам QApplication, живущего в первом треде... или по поводу смены курсора можно? Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: BRE от Июнь 07, 2010, 09:03 IMHO, лучше отказаться от сигналов и в цикле отрисовки метода Redraw проверять сколько времени крутиться цикл и если время больше заданного менять курсор на "занато", а в конце метода восстанавливать его.
Посмотри на: void QTime::start () int QTime::elapsed () const Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 07, 2010, 09:08 хотя это как-то "по-DOS-овски" :) в единичном случае схляет, но хотелось некий регулярный способ получить, чтобы можно было потом просто вызывать одну функцию во всех похожих случаях
и вообще... какой же это "таймер", если события его не проходят, когда приложение занято??? >:( я ожидал бы, чтобы таймер работал в параллельной нити, чтобы его сигналы гарантированно доставлялись через блокирующее соединение - придется наверно такое самому написать Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: BRE от Июнь 07, 2010, 09:26 хотя это как-то "по-DOS-овски" :) в единичном случае схляет, но хотелось некий регулярный способ получить, чтобы можно было потом просто вызывать одну функцию во всех похожих случаях Одну функцию.... Ты же на C++ пишешь, так и думать нужно по другому.Набросаю псевдокод, думаю идея будет понятна. Код
и вообще... какой же это "таймер", если события его не проходят, когда приложение занято??? >:( я ожидал бы, чтобы таймер работал в параллельной нити, чтобы его сигналы гарантированно доставлялись через блокирующее соединение - придется наверно такое самому написать Ты не ожидай, а посмотри как работают таймеры и все будет понятно. ;)Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 07, 2010, 09:34 ну такие подсказки мне уже не нужны - я уже только что сделал и проверил, только лучше, ;) с единственным дополнительным вызовом внутри Redraw, все работает
фишка была в том, чтобы потом сделать регулярный механизм смены курсора для любых операций, которые могут выполняться долго, и которые могут быть внешними, например, библиотечными - тогда чтобы просто перед такой операцией достаточно было создать объект какого-то специального класса, и чтобы курсор волшебным образом менялся, если от момента создания этого объекта, и до момента его уничтожения проходит слишком много времени одним только таймером для этого не обойдешься, сделать придется чуть больше Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: ieroglif от Июнь 07, 2010, 10:01 что происходит:
в основном потоке начинает работать "долгая функция" (в нашем случае это отрисовка). поток её долго и усердно решает. времени на выполнение других задач остаётся поменьше - таймеры (работающие только в основном потоке) начинают зависать, гуй (работающий только в основном потоке) начинает тормозить, прогресс бары перестают корректно работать.. ужас в общем :) решение правильное (имхо, конечно): решение происходит из понимания, что ООП не ООП, а выполнение комманд у нас ПОСЛЕДОВАТЕЛЬНОЕ. и пока одна комманда у нас не отработает - остальные в лучшем случае прижимаются к стенке и протискиваются как могут, а в других случаях так они вообще блокируются. вывод простой - всё что "грузит" основной поток - выводить в отдельный. пусть там работает, сигнальчики отправляет какие хочет. а мы из основного потока, как только стартанём его себе singleShoot(на сколько нужно) запустим. ну и будем вести некий стек типа первый-вошёл=первый-вышел "текуще загружаемых потоков" по которому на каждый singleShoot SLOT метод будет брать элемент из стека, проверять - работает ли тред, и если да, то вешать значок песочных часиков. по окончанию работы тред тоже производит ряд действий каких-то там.. ну и т.д. Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 07, 2010, 10:43 угу, для каких-то приложений примерно так и надо делать, хотя без всяких FIFO можно вполне обойтись
но в моем случае, поскольку пока Redraw не выполнится, гуй и не должен полноценно работать, ибо не с чем а вот таймеры, и все, что к гую не относится, по идее должно... Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: ieroglif от Июнь 07, 2010, 11:25 угу, для каких-то приложений примерно так и надо делать, хотя без всяких FIFO можно вполне обойтись но в моем случае, поскольку пока Redraw не выполнится, гуй и не должен полноценно работать, ибо не с чем поверь, даже самому будет гораздо приятнее, если вместо подвисания гуя (хоть с ним работать и не надо ПОКА ЧТО) у тебя заблокируются элементы которые трогать пока-что не надо и на экране будет написано "Рисуем..." :) а сделать это - 15 минут ;) а теперь к другому случаю: вот у меня есть трейдерский анализатор. работаешь с неразвёрнутым на весь экран графическим отчётом - хорошо,.. а потом захотелось развернуть на полный экран (или обратная процедура, не суть), или изменить настройки расчёта - лично мне очень приятно что пока у меня перерисовывается изображение в полный масштаб - я могу видеть старое, просто растянутое, и продолжать с ним какие-то манипуляции производить. как только подготовились новые графики - они просто отобразились и всё. а некоторые графики каналов только рисуются по минуте-две. и что, это время мне фтыкать на зависшее приложение? а вот таймеры, и все, что к гую не относится, по идее должно... всё, что грузит основной поток в ущерб чему-либо (пользовательское удобство - тоже не маловажный момент.) - оно должно быть отделено в отдельный поток,.. разумеется не в ущерб основному приложению, но у тебя, мне кажется, не тот случай ;) Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 07, 2010, 12:03 Цитировать поверь, даже самому будет гораздо приятнее, если вместо подвисания гуя (хоть с ним работать и не надо ПОКА ЧТО) у тебя заблокируются элементы которые трогать пока-что не надо и на экране будет написано "Рисуем..." Улыбающийся а сделать это - 15 минут мне это сейчас сделать - 1 минута... блокировка элементов давным давно есть, надо только ее вызывать в той функции, которая ответственна за проверку пройденного времени и включение песочных часов а вместо надписи "Рисуем" вполне устраивают песочные часы Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Igors от Июнь 07, 2010, 12:58 а вот таймеры, и все, что к гую не относится, по идее должно... Не должно. События таймера имеют низший приоритет в OC и могут быть получены когда нет др. действий. Надо использовать вторичный цикл событий (см. пост BRE). При этом приходится повозиться чтобы он не тормозил выполнение - это нормальные, стандартные хлопоты.Отделаться песочными часами вряд ли удастся, насколько я помню human interface - задержка (вычисления, перерисовка и.т.п) более полсекунды - app должно показать курсором - задержка 2 и более секунд - app должно выставить индикатор Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 07, 2010, 15:13 мне больше всего нравится собственная идея с параллельным тредом, который индикаторы включает, если надо, но с простой проверкой сколько времени прошло, в данном частном случае получилось нормально, задержка при отрисовке (с вычислениями) порядка нескольких десятков тысяч графических айтемов - не более 3-х секунд, песочные часы вполне уместны
Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: ieroglif от Июнь 08, 2010, 11:30 мне больше всего нравится собственная идея с параллельным тредом, который индикаторы включает, если надо, но с простой проверкой сколько времени прошло, в данном частном случае получилось нормально, задержка при отрисовке (с вычислениями) порядка нескольких десятков тысяч графических айтемов - не более 3-х секунд, песочные часы вполне уместны хм.. вопрос из отдельной области - как отрисовываются десятки тысяч айтемов за 3 секунды?чем отрисовываются? стандартным QPainter? в таком случае какое железо? Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Гурман от Июнь 08, 2010, 13:58 стандартным QPainter, айтемы содержат только текст, никакой графики на сцене нет
уточнил - сейчас пару секунд рисуется сцена с >7000 айтемами, посложнее с >33000 айтемов около 17 секунд (в меньшей сцене все равно есть еще чего делать, поэтому скорость неравномерная) можно и приделать выдачу сообщения для таких сцен, хотя на самом деле, будет в разы быстрее рисоваться, сейчас неоптимально вычисляются bounding rectangle для случаев вложенных айтемов (которых подавляющее большинство), проверял, если кешировать размеры, то отрисовывается в несколько раз быстрее (где-то в 3-5), но надо сесть и аккуратно прописать необходимость перевычисления при изменении вложенных айтемов железо - квадропень с ddr3 Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: ieroglif от Июнь 08, 2010, 14:31 ну вообще да :)
я посчитал, что у меня примерно 40-100 штук элементов отрисовываются :) тогда я спокоен :) Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: Igors от Июнь 08, 2010, 18:06 Если это чисто рисование, то можно делать его по частям, напр.
- отрисовали первые 10К айтемов - показали прогресс % - отрисовали следующие 10К и.т.д. Завести счетчик отрисованных несложно, с "прерываемостью" проблем нет - обнулить тот же счетчик Название: Re: непонятки с таймером, не всегда запускается, см. сообщение Отправлено: ieroglif от Июнь 09, 2010, 11:03 да меня просто вопрос производительности интересовал =)
|