PDA

View Full Version : QGraphicsScene - drawBackground, only one picture



Gruwe
24th July 2012, 17:43
Hi,

I'm coding a programm with a QGraphicsScene and a QGraphicsView of course.
In the GraphicsView I want to use a picture as the backgroundBrush of this View.

I have coded a widget to choose a picture with a QFileDialog. Now you can choose a picture and it will shows on the background of the view...it works fine!

But I have a problem:

The picture fills the complete background. If the background/the View greater than the picture (I have implemented a Zoom too), the picture will repeated on the complete background. But I want that the picture will show only one time at the background, the other space of the background shall be colored in white.

Here is my code:




QImage *loadedPicture = new QImage( sPathOfPicture );

//Brush erstellen und Image als Brush setzen
brushBackground = new QBrush( *loadedPicture );

//Hintergrund-Brush der Zeichenfläche zuweisen
this->setBackgroundBrush( *brushBackground );
this->setCacheMode(QGraphicsView::CacheBackground);



I have googled about this problem, but I can't find any solutions except like "You can reimplement the drawBackground-Methode", etc. but because I'm a newbie, I don't know how I have to do that.

Please, can anyone help me with my problem!

Thanks :)

PS.: I hope you can read my bad english!

wysota
25th July 2012, 08:02
Yeah, you have to reimplement drawBackground() :)

Subclass the view class and write new content for drawBackground() where you will use the given painter to paint the image once, without repeating.

Gruwe
25th July 2012, 15:33
Hi,

thanks for your answer.

So, you don't tell me new things :)

My problem: I'm still a newbie with QT and I have very big problems to reimplement the drawBackground-Methode because I don't know the parameters of this method. For example: Which QPainter is needed to reimplement that method. I think I cannot use any Instance of a QPainter, I can?

Is there a special QPainter für the QGraphicsView?

My programm is almost finished, this is my last problem and I have no idea how I can solve this. Can you give me more explanation to reimplement this methode or can tell me an easier way to solve my problem, please?

Thanks!

wysota
25th July 2012, 15:38
I'm still a newbie with QT
With Qt or with C++?

Gruwe
25th July 2012, 23:15
With Qt or with C++?

More or less with both! ;-)

Ok, give me a chance:

1. I have a QGraphicsScene and a QGraphicsView that works correctly.
2. I have a picture that I want to display in the View.
3. The drawBackground-Methode needs a pointer to a QPainter and a QRect.

My first idea was:

Make a new instance of QPainter, draw in his painter or paste a QImage, etc. Then give this QPainter as an parameter to the drawBackground(). The compiler say that this is ok, but it doesn't work.

Now, I don't know another possible solutions. What do You want to give me help? :confused:

wysota
26th July 2012, 07:53
No. You are not supposed to call this method. You are supposed to write one. You will be given a painter and all that stuff. I'm sorry but this is not a place to teach you C++. Get a good C++ book and read it. You can start with downloading Thinking in C++ (http://mindview.net/Books/TICPP/ThinkingInCPP2e.html/).

Gruwe
26th July 2012, 11:59
Hi,

sorry, I think you don't understand what I mean, it is not a problem with C++, but with Qt. Let me try to explain:


No. You are not supposed to call this method. You are supposed to write one. You will be given a painter and all that stuff.

I know, that I have to write a "new" drawBackground-Methode. So first I have to make a subclass of QGraphicsView with declare a drawBackground-Methode:




class View : public QGraphicsView
...
{
protected:
virtual void drawBackground(...);
...
}


Ok?

Then I have to write the method:



void drawBackground(...)
{
...
}


Ok? Ok! ;)

So, my question was: What have I to write in this NEW method? So, I don't know how the original drawBackground-method painted a Background, I took a look on the Qt-Source, especially on the source of QGraphicsView, of course!
Let me show the source of the original drawBackground-method of QGraphicsView:



/*!
Draws the background of the scene using \a painter, before any items and
the foreground are drawn. Reimplement this function to provide a custom
background for this view.

If all you want is to define a color, texture or gradient for the
background, you can call setBackgroundBrush() instead.

All painting is done in \e scene coordinates. \a rect is the exposed
rectangle.

The default implementation fills \a rect using the view's backgroundBrush.
If no such brush is defined (the default), the scene's drawBackground()
function is called instead.

\sa drawForeground(), QGraphicsScene::drawBackground()
*/
void QGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
Q_D(QGraphicsView);
if (d->scene && d->backgroundBrush.style() == Qt::NoBrush) {
d->scene->drawBackground(painter, rect);
return;
}

painter->fillRect(rect, d->backgroundBrush);
}


Ok, this method gets a pointer on an instance of QPainter and a QRectF. Then the methode will either call the drawBackground-method of the scene or the fillRect-Method of the painter.

In the case the method of the scene is called, this source-code will runs:


/*!
Draws the background of the scene using \a painter, before any items and
the foreground are drawn. Reimplement this function to provide a custom
background for the scene.

All painting is done in \e scene coordinates. The \a rect
parameter is the exposed rectangle.

If all you want is to define a color, texture, or gradient for the
background, you can call setBackgroundBrush() instead.

\sa drawForeground(), drawItems()
*/
void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
{
Q_D(QGraphicsScene);

if (d->backgroundBrush.style() != Qt::NoBrush) {
if (d->painterStateProtection)
painter->save();
painter->setBrushOrigin(0, 0);
painter->fillRect(rect, backgroundBrush());
if (d->painterStateProtection)
painter->restore();
}
}


You can see: Both drawBackground-method use a QPainter. But which painter? Yes, I know that it's the painter that drawBackground of the view gets as an parameter, but...I don't know how I can explain what I mean :(

Ähm, it's difficult to explain my problem:

I dont know how QGraphicsView/Scene works to use a background. Is there a QPainter or so? It looks so, or?

Can you understand my problem now?

edit: Or an other idea: I have only to set an BackgroundBrush. And the drawBackground is only calling from the view/scene automatically, when the scene will be rendered?
And know I have only to write a drawBackground similiar to the original method, but I have to try that this method will paint the backgroundBrush only one time? How can I make that?

wysota
26th July 2012, 14:07
What do you mean "which painter"? You get a painter and the exposed rect and you are supposed to use the painter to draw whatever you want in the scene coordinates determined by the rectangle.

Gruwe
26th July 2012, 16:23
Hi,

I have now coded this:



void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
QRectF &theRect = newRect;

painter->fillRect(theRect, this->backgroundBrush());
}


In the method, where I can choose the picture for the background I define a QRectF with the width and the height of the picture. That QRectF is named newRect.

With this code it works correctly I think. But is this the right and best way?


Thanks

wysota
26th July 2012, 17:35
I would rather use QPainter::drawImage()