Russian Qt Forum
Ноябрь 22, 2024, 13:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Странное падение при рендеринге SVG в QImage  (Прочитано 5312 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Май 28, 2015, 00:47 »

Внутри наследника QWidget в paintEvent() имею такой код (поискал в Инете - везде сделано аналогично):
Код:
    QImage image(size(), QImage::Format_RGB32);
    QPainter p( &image );
    svg->render( &p ); // svg - это QSvgRenderer, который точно содержит то, что нужно
на последней строке падает где-то глубоко внутри, в функции comp_func_SourceOver_sse2(...).

Почти идентичный код из svgview.cpp (пока руки не дошли проверить его работу), пример из самого Qt, также как и у меня выполняется в paintEvent() наследника QWidget:
Код:
buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
            QPainter p(&buffer);
            p.setViewport(0, 0, width(), height());
            p.eraseRect(0, 0, width(), height());
            doc->render(&p);
То есть, существенной разницы с моим вариантом не вижу. Пробовал и Format_ARGB32_Premultiplied, и вьюпорт задавать, и прямоугольник очищать - также падает.

При этом:
Код:
    QPainter p( this ); // рисуем на QWidget
    svg->render( &p );
работает, но мне нужно рисовать на QImage, а не QWidget.

Нашел похожую тему в Сети - при сборке minGW тоже падает в аналогичном месте. Пишут, что при сборке MSVS работает. Но мне надо обязательно GNU, мультиплатформенность...

Кто-нибудь ещё сталкивался? Обходы есть?
Записан

2^7-1 == 127, задумайтесь...
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Май 28, 2015, 08:08 »

Код:
    QPainter p( this ); // рисуем на QWidget
    svg->render( &p );
работает, но мне нужно рисовать на QImage, а не QWidget.

Код
C++ (Qt)
QImage im;
...
QPainter p( &im );
svg->render( &p );
 
Записан

Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Май 28, 2015, 13:07 »

Спасибо, кэп, а посмотреть на первое моё сообщение, где тоже самое написано? Или якобы проблема в том, что QImage размер и тип заданы? Нифига. Проблема не в этом, даже не буду пробовать. Проблема в svg->render() внутри paintEvent(). Сделал рисование в отдельной функции, вызываемой только при изменении цвета или самого svg, ис п преобразованием в QPixmap, а в paintEvent() только drawPixmap(). Так ничего не валится, работает.

Странно, поскольку в примере из Qt рендеринг делается в paintEvent(), но проверять его работу некогда.
« Последнее редактирование: Май 28, 2015, 13:13 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #3 : Сентябрь 15, 2015, 20:39 »

up

Снова влип в эту дырку. При рендеринге SVG, выполняемом в обработчике dropEvent(), глухо падает в глубине... Исследование показало, что в 4.7 (как минимум) есть баг при восстановлении стека, если рисование с SSE2 инструкциями было вызвано из отдельной нити. Так и есть - dropEvent() вызывается не в основной нити, и тогда падает. А при прямых вызовах в основной нити приложения всё отлично работает. Возможно, в 4.8 это было уже исправлено, поскольку все ссылки на дырку содержат версию 4.7. Но в ней можно сделать обход с помощью metaObject()->invokeMethod(...,Qt::QueuedConnection,...). В моём случае этот рендеринг выполняется очень редко, поэтому такой способ вызова меня вполне устраивает. Может кому-нибудь пригодится, если тоже лбом стукнется.

Хотелось, бы, чтобы кто-нибудь подтвердил, что в 4.8 и старше этого бага уже нет.
« Последнее редактирование: Сентябрь 15, 2015, 20:46 от Гурман » Записан

2^7-1 == 127, задумайтесь...
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Сентябрь 16, 2015, 10:17 »

Так и есть - dropEvent() вызывается не в основной нити
Это как это Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #5 : Сентябрь 16, 2015, 13:50 »

Так и есть - dropEvent() вызывается не в основной нити
Это как это Непонимающий

Глубоко не копал, но если в перегруженном методе QGraphicsScene::dropEvent( QGraphicsSceneDragDropEvent *event ) вызвать любую функцию GUI, то будет падение, как при вызове из параллельной нити. Достаточно там просто QMessageBox::warning() вызвать, и на нём рухнет. Может быть, это та же дырка версии 4.7, ковырять некогда.

Впрочем, сейчас проверил  вызовом  qDebug()<<QThread::currentThreadId(); - идентификатор нити один и тот же в её конструкторе и в обработчике dropEvent(). Но тем не менее, эффект имеет место.

Записан

2^7-1 == 127, задумайтесь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.141 секунд. Запросов: 22.