Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved cast QGraphicsEffect* to QGraphicsColorizeEffect* makes program crash.

    General and Desktop
    4
    6
    128
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      Jakob Clausen last edited by

      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();
      
      JonB 1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by Christian Ehrlicher

        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 like const_cast<>, static_cast<>, dynamic_cast<> or reinterpret_cast<> (better avoid using reinterpret cast when possible)

        Qt has to stay free or it will die.

        1 Reply Last reply Reply Quote 4
        • JonB
          JonB @Jakob Clausen last edited by JonB

          @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?

          1 Reply Last reply Reply Quote 1
          • J
            Jakob Clausen last edited by

            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.

            1 Reply Last reply Reply Quote 1
            • mrjj
              mrjj Lifetime Qt Champion last edited by mrjj

              Hi
              Just as info

              You 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.

              1 Reply Last reply Reply Quote 2
              • J
                Jakob Clausen last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post