Solved cast QGraphicsEffect* to QGraphicsColorizeEffect* makes program crash.
-
Hi.
I am trying to get my head around QGraphicsEffect.
I have a bunch of QWidgets and I want to put QGraphicsColorizeEffect on some of them some of the time. So I need to be able to set and remove the effect dynamically.
I can set an effect on a QWidget with QWidget::setGraphicsEffect(), which (I think) works on all types of effects. But there is no function to remove the effect.
But then I thought maybe I can just add an effect to all the widgets, and then use setStrength().
QWidget::setGraphicsEffect() works on all effects and QWidget::graphicsEffect() returns a pointer to a QGraphicsEffect, but setStrength belongs to QGraphicsColorizeEffect.
So maybe I should cast it? But then the program crashes.
My code looks like this:void activateEffect(QWidget* widget) { QGraphicsColorizeEffect* effect; effect = (QGraphicsColorizeEffect*) current->graphicsEffect(); effect->setStrength(0); if (!widget->graphicsEffect()) widget->setGraphicsEffect(new QGraphicsColorizeEffect(widget)); effect = (QGraphicsColorizeEffect*) widget->graphicsEffect(); effect->setStrength(1); current = widget; }
So I guess my questions are
- Is this the right way to do this?
- Why is it crashing. It looks like it crashes at the line with the casting
effect = (QGraphicsColorizeEffect*) current->graphicsEffect();
-
Are you sure
current
is valid? I would guess no. Also I would suggest you to not use C-style casts but the C++ equivalents likeconst_cast<>
,static_cast<>
,dynamic_cast<>
orreinterpret_cast<>
(better avoid using reinterpret cast when possible) -
@Jakob-Clausen said in cast QGraphicsEffect* to QGraphicsColorizeEffect* makes program crash.:
effect = (QGraphicsColorizeEffect*) current->graphicsEffect();
As @Christian-Ehrlicher says. Replace with:
Q_ASSERT(current); effect = dynamic_cast<QGraphicsColorizeEffect*>(current->graphicsEffect()); Q_ASSERT(effect);
What happens?
-
Christian Ehrlicher: Thank you for your input. I think you are right. I will try it on monday. Do you think this is the right way to do something like this?
JonB: Also thank you for your input. I will also try this on monday.
Have a nice weekend.
-
Hi
Just as infoYou can turn off an effect by calling setGraphicsEffect with nullptr
Its logic is like this
void QWidget::setGraphicsEffect(QGraphicsEffect *effect) { Q_D(QWidget); if (d->graphicsEffect == effect) return; if (d->graphicsEffect) { d->invalidateBackingStore(rect()); delete d->graphicsEffect; d->graphicsEffect = 0; } if (effect) { // Set new effect. QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this); QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced); d->graphicsEffect = effect; effect->d_func()->setGraphicsEffectSource(source); update(); } d->updateIsOpaque(); }
so nothing bad happens to give it a null pointer since it will delete the one it has.
But if you only use QGraphicsColorizeEffect, i like your idea with setStrength() as
then we dont go around deleting and creating QGraphicsColorizeEffect over and over. -
Thank you all for your help.
current was not valid. It was a brainfart on my part.
But thank you very much for your input.