2

How to disable setGraphicsEffect inheritance to children in Qt?

For example, imagine my project has this hierarchy:

enter image description here

When I apply a shadow with setGraphicsEffect to the frame the line edit will inherit that shadow effect, and I don't want that. This is what I'am getting:

enter image description here

As you can see, there's a shadow around the letters of the line edit. Any idea how to fix this?

One more thing.. visibly in the image above the MainWindow has some flags like Qt::FramelessWindowHint and Qt::WA_TranslucentBackground so the frame is supposed to be the "window", and the frame automatically resizes when I resize the MainWindow so I can't change that hierarchy.

As requested by Timusan here is the code of the shadow: Qt: shadow around window

To apply it to the frame:

CustomShadowEffect *shadow = new CustomShadowEffect();    
shadow->setColor(c);  
shadow->setDistance(scale);  
shadow->setBlurRadius(blur_radius);  
ui->frame->setGraphicsEffect(shadow);  

UPDATE

layout()->addWidget(ui->lineEdit);  
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Hi and welcome to SO! Well formed question, but could you also post a code sample of how you applied the shadow? When folks see the code, they might get a better idea of what you might be missing. – Timusan Jun 24 '15 at 23:51
  • Shadow code (first answer): http://stackoverflow.com/questions/23718827/qt-shadow-around-window How I applied the shadow: shadow->setColor(c); shadow->setDistance(scale); shadow->setBlurRadius(blur_radius); ui->frame->setGraphicsEffect(shadow); @Timusan – Ricardo Gomes Jun 25 '15 at 00:02

1 Answers1

1

Documentation of QGraphicsItem::setGraphicsEffect states that

Note: This function will apply the effect on itself and all its children.

thus the behaivor you are expecting is correct.

What I'd suggest is overriding the graphics item on the QLineEdit explicitly by calling either setGraphicsEffect(NULL) or by getting the default text effect of the line edit and then setting it back after your custom effect on the frame has been applied. I'm not sure if the line edit has a default effect or not, thus not sure if the NULL approach will do.

UPDATE

As stated by the OP the proposed way of overriding the existing effect by calling QGraphicsItem::setGraphicsEffect with null does not work. So given that I see 2 further possibilies:

  • Don't make the QLineEdit a child of the frame (not sure if that is possible, you mentioned that frame cannot be unbound from the window but nothing about frame to line edit relationship constraints).
  • Since you already have subclassed the graphics effect with your CustomShadowEffect you could tweak the draw() method to ignore calls with QPainter that belongs to the line edit. What you could do is keep a list of ignored QPaintDevice instances in the effect - QWidget inherits QPaintDevice and you can query the QPaintDevice pointer from the QPainter via QPainter::device, so you can simply add the widgets to your internal list and then in the draw method compare the QPaintDevice of the incoming QPainter to the ignored ones.
Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71
  • 1
    Setting setGraphicsEffect(NULL) to the line edit does not seem to work. Also getting the text effect is useless because it doesn't have one. The way inheritance works here is different. It doesn't set the same effect to the children, instead Qt backend will detect that the frame have children and will render them with the same effect.. – Ricardo Gomes Jun 24 '15 at 23:14
  • @RicardoGomes thanks for the feedback:) I tried to give additional ideas if they are of any help. – Rudolfs Bundulis Jun 25 '15 at 08:23
  • Thanks @RudolfsBundulis for the ideas. As I said before the first idea is impossible. This is what happens when I do that: http://i.imgur.com/ATv8iti.png I need that QLineEdit above the frame.. The second ideia might do the trick but I have no clue how to do that, and painter->device() always returns the same pointer. – Ricardo Gomes Jun 25 '15 at 12:33
  • @RicardoGomes - as for the first, well yeah, by default the items will be managed by the layout not to overlap, but i think that by tweaking the geometry of the second one you can actually achieve that they overlap even if they are not parent and child but sadly I'm don't have a working example. As for the second - glad you tried that out. If the pointer is always the same I assume that the `draw()` method is only called for the parent widget and then it uses the same `QPainter` to draw the children without explicitly calling it again (seems a bit weird though). If so I'm sadly out of ideas. – Rudolfs Bundulis Jun 25 '15 at 12:48
  • We found a way to fix it! Adding the QLineEdit to the layout(same as the first idea) did the trick: layout()->addWidget(ui->lineEdit); Thanks again for everything. – Ricardo Gomes Jun 25 '15 at 14:07
  • @RicardoGomes and how did you make both widgets overlap? Which layout was it? – Rudolfs Bundulis Jun 25 '15 at 14:24
  • I didn't use MainWindow centralWidget layout. Instead we used MainWindow layout and it worked. The only problem is that Qt is printing an warning that I shouldn't use that layout.. – Ricardo Gomes Jun 25 '15 at 14:38