Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Производительность QSvgRenderer + QGraphicsView 
:(
    Опции темы
Ground
Дата 11.9.2011, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 321
Регистрация: 27.2.2006
Где: Комсомольск

Репутация: нет
Всего: 1



Доброго времени суток!
Есть задача: сделать QGraphisView, где в качестве фона будет SVG изображение и несколько постоянно перерисовывающихся виджетов.
Проблема: низкая производительность (в частности - скроллинг рывками), подробности - ниже.
Основная сложность при решении данной задачи - перерисовывающиеся виджеты. Время обновления - 20-40мс.


Вариант 1:
SVG рендерится в QGraphicsView::drawBackground() с опцией QGraphicsView::setCacheMode(QGraphicsView::CacheBackground);
В такой реализации загрузка CPU = 0%, но скроллинг изображения осуществляется рывками.
Если убрать QGraphicsView::setCacheMode(QGraphicsView::CacheBackground); - скроллинг становится плавным, но загрузка CPU = 50% (обновляющиеся виджеты виноваты, постоянно вызывают рендеринг фона, без кеширования - очень накладно).
Код
graphicsView::graphicsView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent)
{
    setRenderHint(QPainter::Antialiasing);
    setCacheMode(QGraphicsView::CacheBackground);

    renderer = new QSvgRenderer(this);
    renderer->load(QString("map.svg"));

    setSceneRect(renderer->viewBoxF());
}

void graphicsView::drawBackground(QPainter* painter, const QRectF&)
{
    renderer->render(painter, renderer->viewBoxF());
}



Вариант 2:
Этот вариант аналогичен первому за тем исключением, что добавлена строка setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
При этом варианте скроллинг - плавный, но загрузка процессора CPU = 50%, хоть с опцией QGraphicsView::CacheBackground, хоть без нее.
Код дублировать не буду.


Вариант 3:
SVG в QGraphicsScene добавляется через QGraphicsSvgItem с опцией QGraphicsSvgItem::setCacheMode(QGraphicsItem::DeviceCoordinateCache);
Результат: скроллинг - плавный, CPU - загрузка средняя = 25%.
Код
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(500, 500);
    // Главный виджет
    QWidget* wgtMain = new QWidget(this);
    wgtMain->setBackgroundRole(QPalette::Base);
    // Графическая сцена
    QGraphicsScene* scene = new QGraphicsScene(wgtMain);
    scene->setItemIndexMethod(QGraphicsScene::NoIndex);

    // Тестовый виджет
    testWidget** test = new testWidget* [3];
    for (qint8 i = 0; i < 3; i++)
    {
        test[i] = new testWidget();
        test[i]->move(i * 300 + 50, 0);
        scene->addWidget(test[i]);
    }

    QGraphicsSvgItem* tst = new QGraphicsSvgItem("map.svg");
    tst->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    scene->addItem(tst);
    
    QGraphicsView* lblBackgroundImage = new graphicsView(scene, wgtMain);
    lblBackgroundImage->setGeometry(0, 55, width(), height() - 55);
    lblBackgroundImage->setDragMode(QGraphicsView::ScrollHandDrag);

    setCentralWidget(wgtMain);
}



Код тестового виджета (ничего интересного - банальная перерисовка по таймеру):
Код
testWidget::testWidget(QWidget *parent) :
    QWidget(parent)
{
    resize(200, 200);
    QTimer* processTimer = new QTimer();
    processTimer->setInterval(40);
    connect(processTimer, SIGNAL(timeout()), this, SLOT(update()));
    processTimer->start();
}

void testWidget::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    static int i = 0;
    i+=1;
    p.setBrush((QColor)i);
    p.drawRect(0, 0, 200, 200);
}



Вот и как найти золотую середину - без тормозов при скроллинге и без загрузки CPU при прорисовке виджетов?
Уже почти неделю мучаюсь с этой проблемой, перепробовал все флаги - безрезультатно. Буду очень благодарен за помощь.
PS: Если нужен будет минимальный проект с наблюдаемой проблемой - могу выложить.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0553 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.