Название: При выводе текста через QPainter потребляется много ресурсов Отправлено: Командор от Март 07, 2011, 09:24 Мне нужно на виджете выводить текст, который регулярно меняется (либо по сигналам, либо по событиям). Текст вывожу следующим образом:
Код
При нажатии на любую клавишу на экране меняется текст. Если удерживать клавишу, то системный монитор показывает загрузку 20-25% (Windows 7, AMD 5000+). Но если раскомментировать таймер, то загрузка 5-7%. И вот не могу понять, почему при событиях от таймера, которых явно больше, чем при удерживании клавиши, загрузка меньше? Т.е. получается, что при событии от клавиатуры возникают дополнительные задержки. Ни у кого нет соображений? P.S. Если переменную k обнулить, то видно, что количество событий от таймера и от клавиатуры примерно одинаково (20-25 раз в секунду). Но загрузка процессора все равно в три раза меньше. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: dd от Март 07, 2011, 14:37 Можно по нажатию запускать тайемр, а по отпускании (keyReleaseEvent) удалять его. Как вариант.
Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: Командор от Март 07, 2011, 15:53 Можно по нажатию запускать тайемр, а по отпускании (keyReleaseEvent) удалять его. Как вариант. Можно, но у каждого пользователя свои установки клавиатуры (задержка при повторении, число повторений в сек). Впрочем, увеличил количество элементов в два раза, нагрузка что при таймере, что при клавиатуре почти одинаковая - 30%. Что-то не то. Вот только что наткнулся на этом сайте на PatherCommander, запустил, открыл большую папку, жму вниз - файлы бегут вверх - загрузка 10-12%. Открыл исходники QTreeView и QAbstractItemView - так и не смог найти, каким образом там выводится текст элементов. Насколько я понял drawtext - это самый быстрый способ вывод текста. Но получается, что навороченный QTreeView выводит быстрее моей простейшей реализации. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: dd от Март 07, 2011, 17:17 В том и дело, что интервал разный.
А с моим вариантом будет одинаковый и настраиваемый. Более правильно. Жрет проц - очень похоже на рекурсию. Обычно бывает, когда бесконечно перерисовывается окно по какой-нибудь причине. Надо сделать примерно так: void keyPressEvent(QKeyEvent* event) { if(!flag) { flag = true; // start timer here } } void keyReleaseEvent (QKeyEvent*) { if(flag) { flag = false; // stop timer here } } И еще. Чтоюы рисовало быстрее, откшлючи антиалиасинг текста. сли он все- таки нужен, несложно сделать, чтобы он отключался на время циклической перерисовки, а потом включался. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: ufna от Март 07, 2011, 23:31 делай update() вместо repaint() - зачем насиловать программу?
Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: Командор от Март 07, 2011, 23:49 делай update() вместо repaint() - зачем насиловать программу? Под виндой разницы нет, в линухе небольшая разница есть. update(), как я понял, дает эффект, если есть несколько виджетов, лежащих друг над другом или перескающиеся, тогда регион перерисовки будет объединен и сообщение будет более адекватным, но тут такого нет. Вообще, я делаю легкий виртуальный listbox. В Qt это велосипед, я понимаю, но легкий (школьник вместо урала). Однако легкости не видно. Понятно, что нужно копать в сторону Qtreeview и создать нужную модель. Но все же интересно, почему элементарный вывод через drawtext так грузит систему. Анти-аллиасинг, бэкграундфил, вывод через простейший drawtext без наворотов типа переноса строк ничего не дали. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: dd от Март 08, 2011, 00:09 Текст рисуется тяжело, это факт.
Прочувствовал это на моб устройствах. В 4.7 появился класс для быстрой отрисовки редкоизменяемого текста. Могу ошибиться, вроде QStaticText. В описани изменений к этой версии он указан, на сайте глануть можно. ---------- Добавлено ----------- http://www.kubuntu.ru/node/6945 - тут написано про это А вообще раз 50 миллисекунд рисовать 30 строк - это похоже на алгоритмическую ошибку. Если в реальности такая нагрузка имеет место быть (например при прогрутке), проще делать рендеринг в пиксмап и его крутить. Или юзать механизм скроллинга, или другие способы оптимизации. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: Командор от Март 08, 2011, 00:29 Если в реальности такая нагрузка имеет место быть (например при прогрутке), проще делать рендеринг в пиксмап и его крутить. Или юзать механизм скроллинга, или другие способы оптимизации. А можно классы-функции? А именно - рендеринг в пиксмап, скроллинг? Скроллинг смотрел, там вроде обычный move() вьюпорта, который в конце концов вызывает repaint/update с регионом. Мне нужна прокрутка, но построчная, думал ее сделать виртуальной, т.е. просто отрисовывать в определенных местах текст. Одно успокаивает - что в эксплоэре загрузка 20-30% при прокрутке списка. Но не успокаивает, что в PatherCommander при "тупом" наследовании рисование быстрее, 10% загрузки процессора. Тотал и фригейт столько занимают, а по крайней мере тотал нынешиний все еще пишется на Делфи 2. Т.е. чисто технически, в этом плане новейший Qt не уступает Делфи 2. Но вот мне это недоступно, нахожусь на уровне эксплоера. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: dd от Март 08, 2011, 00:40 Скроллинг виджета реализован побитовым копированием. То есть максимально быстро.
Однако оно должно быть отрисовано уже, то есть не прокатит с вариантом "виртуального" списка (из термина MS). На самом деле не вижу проблемы. Тормозит при прокрутке? Оптимизируй, чтобы строки не рисовалисть текстом. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: ufna от Март 08, 2011, 01:05 Под виндой разницы нет, в линухе небольшая разница есть. Разве? update() кидает сие событие в очередь, reapint() жестко перерисовывает при вызове. Или я не прав? Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: Командор от Март 08, 2011, 01:28 Под виндой разницы нет, в линухе небольшая разница есть. Разве? update() кидает сие событие в очередь, reapint() жестко перерисовывает при вызове. Или я не прав? В данном случае лучше repaint(). Потому как если еще добавить селект и "логические" виджеты (т.е. когда вместо цикла drawtext на несколько строк есть несколько дочерних виджетов на несколько строк с одним drawtext и вызывается repaint родителя), то будут тормоза, но только в линухе, винде как я понял в среднем, похрен на update(). Т.е. upadte() лучше понимает линух. Я хочу уточнить. Лет 10 назад я написал свой листбокс на турбопаксаль. Реализованы все основные функции - перемещение вверх-вниз, Pg-Up-down, Home-End, появление-исчезновение объектов в списке. И решил, что сделаю свой qlistbox, охрененно быстрый. Однако "тупо" рисовать текст получается накладно. Буду смотреть в сторону побитового копирования, а новое буду рисовать заново. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: ufna от Март 08, 2011, 08:28 я не вижу чем тут лучше repaint(). Только что глянул доки и они подтвердили мои догадки. repaint() - немедленно вызывает процесс перерисовки, в то время как update() ставит событие в очередь основного цикла. repaint(), кстати, может легко вызывать рекурсию, апдейт - нет. Потому я очень рекомендую использовать апдейт, если нет четкой нужды (а ее по сабжу не видно) перерисовывать моментально.
и да, тормозит если текст - рисуй НЕ текстом, как уже сказали. Техника черт знает каких времен - шрифт растровый, картинками. Кэшируй в слова, тогда при скролле будет быстро бегать ( + во втором потоке всегда можно подрисовывать "не показанные" несколько айтемов для совсем быстрой прокрутки). На самом деле это для мобильных устройств. Подобный код на десктопе если вызывает такую нагрузку проца - это странно. Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: _govorilka от Март 08, 2011, 10:02 Нагрузку на проц скорее всего создаёт алгоритм разбиения текста на строки с последующим их выравниванием. Для рисования текста попробуйте использовать функцию:
Код: void QPainter::drawText ( const QPoint & position, const QString & text ) Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: _govorilka от Март 08, 2011, 10:06 и да, тормозит если текст - рисуй НЕ текстом, как уже сказали. Техника черт знает каких времен - шрифт растровый, картинками. Кэшируй в слова, тогда при скролле будет быстро бегать ( + во втором потоке всегда можно подрисовывать "не показанные" несколько айтемов для совсем быстрой прокрутки). На самом деле это для мобильных устройств. Подобный код на десктопе если вызывает такую нагрузку проца - это странно. Qt сама создаёт внеэкранный буфер для каждого виджета, рисование картинок здесь мне кажется не поможет. А вот замена repaint() на update() ... Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: ufna от Март 08, 2011, 10:58 Qt сама создаёт внеэкранный буфер для каждого виджета, рисование картинок здесь мне кажется не поможет. А вот замена repaint() на update() ... поможет и еще как! Надо же правильно буферизировать и кэшировать Название: Re: При выводе текста через QPainter потребляется много ресурсов Отправлено: dd от Март 08, 2011, 14:45 У меня список самопальный под слабый девайс.
С отрисовкой текста можно было забыть об анимации. Сделал скроллинг посредством QPixmap и отлично работает даже с нелинейной анимацией. Плавно и красиво. |