0

I want to apply blur effect to a gradient generated by GRadialGradient and rendered by QPainter.Looks like for such graphical effects I have to provide a pixmap and a QGraphicsScene and then call the ->render() method but I couldn't find any ways to add a QPainter directly into any subclass of QGraphicsItem.

So is there any way to do that?
I think converting the QPainter render results to QPixmap can solve the problem.But I don't know how.And I don't know how the performance of converting then applying the blur effect in real-time would be.

Here's an excerpt from what I've written so far:

void MainWindow::paintEvent(QPaintEvent *event){
    Q_UNUSED(event);

    QRadialGradient grad(QPoint(this->width()/2,this->height()/2) , 50);
    grad.setSpread(QGradient::RepeatSpread);
    grad.setColorAt(0 , QColor(0,0,0));
    grad.setColorAt(1 , QColor(100,100,100));
    QPainter paint(this);

    paint.setRenderHint(QPainter::Antialiasing , true);

    QRectF r1(0,0,this->width(),this->height());

    paint.drawRect(r1);
    QBrush brush(grad);
    paint.fillRect(r1 , brush);
...
...
}

And here's the results:

enter image description here

Thanks.

Parsa Mousavi
  • 1,052
  • 1
  • 13
  • 31
  • your question is confusing, do you want the MainWindow to have the blur effect on the gradient you use? – eyllanesc Aug 09 '20 at 21:06
  • @eyllanesc The blur effect is actually applied to the **QGraphicsItem** instance that will be added to a **QGraphicsScene**.It has nothing to do with my **MainWindow**.I don't want the effect to be window-wide(in this specific case since the size of ```r1``` is equal to the window size(line 12) it's looks like it's window-wide.But it isn't). – Parsa Mousavi Aug 09 '20 at 21:10
  • mmm, in your code I don't see anything related to QGraphicsItems so your example generates confusion. I think you have an XY problem, so far I do not understand what your underlying objective is, but in your entire post you talk about a possible solution without knowing if that solution is adequate for your unknown underlying problem. – eyllanesc Aug 09 '20 at 21:13
  • @eyllanesc I haven't added anything just yet related to ```QGraphicsScene``` because still I don't know exactly what should I do.The code is just to demonstrate the painter that I've created to further reduce the confusion.If it's confusing I can remove that.And also forget about the code.The question is straightforward.Let me clear the confusion:How to cache the results of **QPainter** rendering into **QPixmap**? – Parsa Mousavi Aug 09 '20 at 21:21
  • In the solution that link the product is a QImage, and from what I understand is that you want to obtain a QPixmap, if so then you can use QPixmap::fromImage() – eyllanesc Aug 09 '20 at 21:24
  • @eyllanesc What I'm looking for is to be able to apply the line 8 of that example not to convert QPixmap to QImage.Since I cannot create a QGraphicsItem out of a QPointer, I'm stuck. – Parsa Mousavi Aug 09 '20 at 21:29
  • Your comments are more confusing, take the time to better rewrite your post and clearly explain what you want to get. From what I understand is that you want to create a QPixmap where the concentric image + blur effect is displayed, and it has nothing to do with the widgets, am I correct? – eyllanesc Aug 09 '20 at 21:34
  • @eyllanesc **QPainter rendering -> QPixmap -> Blur effect (->setGraphicsEffect) -> Final compositing and presentation via QGraphicsScene** – Parsa Mousavi Aug 09 '20 at 21:36
  • From what I understand you want a QGraphicsItem in the scene that shows the image of the circular gradient + blur effect – eyllanesc Aug 09 '20 at 21:39
  • @eyllanesc Exactly.But that's a special circular gradient.It's not an image. – Parsa Mousavi Aug 09 '20 at 21:39
  • So because it doesn't point to it precisely in your question, it has nothing to do with QPixmap in that. To create a QPixmap it is not necessary to create or use a QPixmap, why not create a QGraphicsRectItem that has that radial gradient as a brush and then apply the blur effect to the QGraphicsRectItem? `QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100); item->setBrush(QBrush(grad)); item->setGraphicsEffect(effect);` – eyllanesc Aug 09 '20 at 21:42
  • @eyllanesc After messing around with it for some time I changed the approach and started from scratch this time by using **QGraphicsView** to show the results instead of ```->render```(my problem was with the first parameter: **painter**).Now your suggestions work for me and I can see the gradient but still there's one problem: the blur effect doesn't work even though ```item->graphicsEffect()``` doesn't return ```nullptr```.And even when I set the **blurRadius** to 100 the image is till sharp.Any idea? BTW [here](https://pastebin.com/Cn0tfB85)'s an excerpt of it – Parsa Mousavi Aug 10 '20 at 19:38
  • important concept: SCOPE OF VARIABLES IN METHODS, change to `QGraphicsBlurEffect *blur = new QGraphicsBlurEffect(this); blur->setBlurRadius(100); item->setGraphicsEffect(blur);` – eyllanesc Aug 10 '20 at 19:44
  • @eyllanesc Yeah that's it.Finally you can post it as the answer if you want.Thanks for your patience and time. – Parsa Mousavi Aug 10 '20 at 20:07

1 Answers1

1

Your question is clearly an XY problem, instead of asking about the underlying problem: How to display a QGraphicsItem that shows the circular gradient + blur effect, questions about an attempted solution: convert to QPixmap.

In this case, the simplest thing is to use a QGraphicsRectItem where you set the gradient as brush and the effect is applied to that item:

QGraphicsBlurEffect *effect = new QGraphicsBlurEffect(this);     
effect->setBlurRadius(100);

QRadialGradient grad(QPoint(50, 50), 50);
grad.setSpread(QGradient::RepeatSpread);
grad.setColorAt(0 , QColor(0, 0, 0));
grad.setColorAt(1 , QColor(100, 100, 100));

QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100); 
item->setBrush(QBrush(grad));
item->setGraphicsEffect(effect);
eyllanesc
  • 235,170
  • 19
  • 170
  • 241