Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: n4ela от Ноябрь 08, 2009, 03:36



Название: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 08, 2009, 03:36
Есть QWidget вывожу на него картинки QSvgWidget
Код
C++ (Qt)
 
QList <QSvgWidget*> ground;
for ( int i = 0; i < 5; i++ )
   {
       ground.append( new QSvgWidget( this ) );
       ground.back()->resize( x, x );
       ground.back()->setGeometry( xX, x, x, x );
       ground.back()->load( QString( ":/spheres.svg" ) );
       ground.back()->show();
       xX += x;
   }
 
По ресайзу окна, вызываю этот метод, получается, что картинки с новым размером (x зависит от размера окна) выводятся, но при этом старые то же видны. очищать backGround пробовал.
Нашел один способ:
Код
C++ (Qt)
   for ( int i = 0; i < 5; i++ )
       ground[i]->hide();
 
Но так получается что я их скрываю, а не удаляю.


Название: Re: QSvg cтереть объект
Отправлено: lit-uriy от Ноябрь 08, 2009, 05:40
посмотри пример:
%QTDIR%\examples\painting\svgviewer


Название: Re: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 08, 2009, 11:25
Смотрел, честно говоря не понял.
Додумал еще до одного решения: сначала один раз отрисовать объекты, а потом при ресайзе окна вызывать метод, где цикл в котором происходит resize и setGeometry каждого отрисованого элемента.


Название: Re: QSvg cтереть объект
Отправлено: _OLEGator_ от Ноябрь 08, 2009, 13:42
если тебе надо просто вывести набор svg-картинок на форму, то почему бы не переопеределить рисование формы, в котором выводить каждую картинку с помощью QSvgRenderer, так не надо будет в цикле менять размеры, а рисовать так:
Код
C++ (Qt)
QSvgRenderer::render ( QPainter * painter, const QRectF & bounds )


Название: Re: QSvg cтереть объект
Отправлено: lit-uriy от Ноябрь 08, 2009, 14:46
n4ela, у тебя какая версия Qt?
В Qt 4.4 этом примере использовалось наследование от QWidget, а в Qt 4.5 уже Графическое представление используется.
Вот фрагмент кода из Qt 4.4:
h
Код
C++ (Qt)
class SvgNativeView : public QWidget
{
   Q_OBJECT
 
public:
   SvgNativeView(const QString &file, QWidget *parent=0);
 
   virtual QSize sizeHint() const;
protected:
   virtual void paintEvent(QPaintEvent *event);
   virtual void wheelEvent(QWheelEvent *event);
 
private:
   QSvgRenderer *doc;
};
 
cpp
Код
C++ (Qt)
SvgNativeView::SvgNativeView(const QString &file, QWidget *parent)
   : QWidget(parent)
{
   doc = new QSvgRenderer(file, this);
   connect(doc, SIGNAL(repaintNeeded()),
           this, SLOT(update()));
}
 
void SvgNativeView::paintEvent(QPaintEvent *)
{
   QPainter p(this);
   p.setViewport(0, 0, width(), height());
   doc->render(&p);
}
 
QSize SvgNativeView::sizeHint() const
{
   if (doc)
       return doc->defaultSize();
   return QWidget::sizeHint();
}
 
void SvgNativeView::wheelEvent(QWheelEvent *e)
{
   const double diff = 0.1;
   QSize size = doc->defaultSize();
   int width  = size.width();
   int height = size.height();
   if (e->delta() > 0) {
       width = int(this->width()+this->width()*diff);
       height = int(this->height()+this->height()*diff);
   } else {
       width  = int(this->width()-this->width()*diff);
       height = int(this->height()-this->height()*diff);
   }
   resize(width, height);
}
 


Название: Re: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 09, 2009, 23:40
Спасибо. У меня qt4.5 там пример другой был.
А вот еще вопрос, возможно ли рисовать поверх QSvgWidget?
Я пытаюсь рисовать в QPainter'ом но часть рисунка пересекается с QSvgWidget, и картинка из виджета оказывается поверх картинки паинтера.


Название: Re: QSvg cтереть объект
Отправлено: _OLEGator_ от Ноябрь 10, 2009, 01:02
конечно можно. только смысл в QSvgWidget если ты будешь сам рисовать svg.
а рисовать так - переопределяешь paintEvent, внутри него:
Код
C++ (Qt)
void NewWidget::paintEvent ( QPaintEvent * e )
{
 QSvgWidget::paintEvent(e); //рисуется содержимое QSvgWidget'а
 //дальше рисуешь свое.
}


Название: Re: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 10, 2009, 01:12
Спасибо, завтра попробую.
А смысл в том что есть картинка в svg. Которую я вывожу и для лучшего восприятия надо нарисовать решетку поверх этой картинки, получается такое игровое поле. Решетку можно включить или отключить, так что вариант сразу прорисовать ее на svg'eшной картинки не подходил.


Название: Re: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 13, 2009, 18:38
Попробовал почему то не получается.
Делаю так:
Код
C++ (Qt)
void Field::paintEvent( QPaintEvent *event )
{
   QSvgWidget::paintEvent( event );
   QPainter painter( this );
   painter.setRenderHint( QPainter::Antialiasing );
   painter.drawLine( 0, 0, 500, 500 );
}
 
Получаю: ошибка: некорректный вызов элемента-функции ‘virtual void QSvgWidget::paintEvent(QPaintEvent*)’ без объекта
Если делаю так:
Код
C++ (Qt)
void Field::paintEvent( QPaintEvent *event )
{
   svgL->paintEvent( event );
   QPainter painter( this );
   painter.setRenderHint( QPainter::Antialiasing );
   painter.drawLine( 0, 0, 500, 500 );
}
 
Получаю: /usr/include/QtSvg/qsvgwidget.h:74: ошибка: ‘virtual void QSvgWidget::paintEvent(QPaintEvent*)’ is protected

svgL объявлена так:
QSvgWidget *svgL;
Field мой класс унаследованный от QWidget


Название: Re: QSvg cтереть объект
Отправлено: lit-uriy от Ноябрь 13, 2009, 19:35
>>Field мой класс унаследованный от QWidget
QSvgWidget::paintEvent(e);
и
svgL->paintEvent( event );
возможны только для наследника QSvgWidget


Название: Re: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 13, 2009, 19:59
т.е. мне нужно еще создать еще один класс унаследованный от QSvgWidget и там переопределить QPaintEvent а в своей программе использовать место QSvgWidget этот класс?
Значит делаю так:
mysvgwidget.h
Код
C++ (Qt)
#ifndef MYSVGWIDGET_H
#define MYSVGWIDGET_H
 
#include <QSvgWidget>
 
class MySvgWidget : public QSvgWidget
{
   Q_OBJECT;
public:
//    MySvgWidget( QWidget *parent=0 );
 
};
 
#endif
 
mysvgwidget.cpp
Код
C++ (Qt)
#include "mysvgwidget.h"
 
//MySvgWidget::MySvgWidget( QWidget *parent )
//{
//}
 
Появляется ошибка про конструктор. Если я расскоментирую строки конструктора, то картинка из виджета выводится в новом окне. То есть мне нужно использовать конструктор который оригинального QSvgWidget а как это сделать?


Название: Re: QSvg cтереть объект
Отправлено: lit-uriy от Ноябрь 13, 2009, 23:10
Тебе нужно иницализировать базовый класс (от которого наследуешся). Пример можешь посмотреть в любом исходнике Qt, хотябы тот же Ответ #4 (http://www.prog.org.ru/index.php?topic=11211.msg68543#msg68543).


Название: Re: QSvg cтереть объект
Отправлено: n4ela от Ноябрь 14, 2009, 00:20
Спасибо.