Results 1 to 5 of 5

Thread: Changing a QGraphicsItem's transparency as a whole

  1. #1
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Changing a QGraphicsItem's transparency as a whole

    I'm trying to change the transparency of this QGraphicsItem-inheriting shape.



    Because of the way the drop shadow is drawn, this happens when I change the object's transparency...



    I've thought about only drawing the parts of the shadow that will be seen, but I don't think that will work with these shapes:



    I want the graphics item to be drawn and then have the opacity be changed on the resulting drawing, thus avoiding that you can see the full drop shadow through the shape itself. How can I change the QGraphicsItem's transparency as a whole?

  2. #2
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Changing a QGraphicsItem's transparency as a whole

    QPainter's opacity is applied to all drawing operations individually, so simple item->setOpacity(x) is not enough.
    I have two ideas, first is to erase the area where you have rendered shadow under the item ( by setting QPainter's brush to QPainter::background() ), but this will erase everything you have rendered, including other items rendered under current item. Code sample (paint method for simple ellipse item):
    Qt Code:
    1. void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ){
    2. const qreal opaque = 1.0;
    3. const qreal transparent = 0.5;
    4. const QRect shadow(10,10,100,100);
    5. const QRect item(0,0,100,100);
    6.  
    7. painter->setOpacity( transparent );
    8. painter->setBrush( QBrush(Qt::black) );
    9. painter->drawEllipse( shadow );
    10.  
    11. painter->setOpacity( opaque );
    12. painter->setBrush( painter->background() );
    13. painter->drawEllipse( item );
    14.  
    15.  
    16. painter->setOpacity( transparent );
    17. painter->setBrush( QBrush(Qt::red) );
    18. painter->drawEllipse( item );
    19. }
    To copy to clipboard, switch view to plain text mode 
    Another way is to set proper clip path for painter when rendering shadow, so it will not be rendered in the area under item. This solution will not erase background items.
    Idea is to let the painter draw shadow everywhere except the item's area, so I have used QPainterPath::subtracted to create proper painting area (compilable sample):
    Qt Code:
    1. #include <QtCore>
    2. #include <QtGui>
    3.  
    4. class RectItem : public QGraphicsItem{
    5. public:
    6. RectItem( QGraphicsItem * parent = NULL ) : QGraphicsItem(parent){
    7.  
    8. }
    9. QRectF boundingRect() const{
    10. return QRectF(0,0,150,150);
    11. }
    12. void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ){
    13. const qreal transparent = 0.5;
    14. const QRect shadow(10,10,100,100);
    15. const QRect item(0,0,100,100);
    16.  
    17. QPainterPath scene; scene.addRect(0,0,300,300); // scene rectangle, hard coded here, but its just an example
    18. QPainterPath shadowp; shadowp.addEllipse(item);
    19. shadowp = scene.subtracted(shadowp); // can render everywhere except item's area
    20. painter->setClipPath(shadowp);
    21.  
    22. painter->setOpacity( transparent );
    23. painter->setBrush( QBrush(Qt::black) );
    24. painter->drawEllipse( shadow );
    25.  
    26. QPainterPath itemPath; itemPath.addEllipse(item);
    27. painter->setClipPath(itemPath); // you can use setClipPath(scene) as well
    28.  
    29. painter->setBrush( QBrush(Qt::red) );
    30. painter->drawEllipse( item );
    31. }
    32. };
    33.  
    34. int main(int argc, char *argv[])
    35. {
    36. QApplication a(argc, argv);
    37.  
    38. QGraphicsView * view = new QGraphicsView();
    39. QGraphicsScene * scene = new QGraphicsScene(QRectF(0,0,300,300));
    40. view->setScene(scene);
    41. view->show();
    42. RectItem * rect = new RectItem();
    43. rect->setPos(20,20);
    44. RectItem * rect2 = new RectItem();
    45. rect2->setPos(40,50);
    46. scene->addItem(rect);
    47. scene->addItem(rect2);
    48.  
    49. return a.exec();
    50. }
    To copy to clipboard, switch view to plain text mode 
    I think this should be what you are looking for. Probably you can use your item's shape() method instead of create QPainterPath by hand, but this sample is just to present the idea. Hope it helps.

  3. The following user says thank you to stampede for this useful post:

    blooglet (11th April 2011)

  4. #3
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Changing a QGraphicsItem's transparency as a whole

    I used the second method. It works perfectly. Thanks!


  5. #4
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Changing a QGraphicsItem's transparency as a whole

    (Apologies for digging up this older topic, but it's directly related to this issue.)

    I've noticed that this technique produces bad drawing results on some shapes, likely due to rounding:



    I suspect that this may have something to do with the problem:

    QPainterPath::subtracted
    Returns a path which is p's fill area subtracted from this path's fill area.
    Set operations on paths will treat the paths as areas. Non-closed paths will be treated as implicitly closed. Bezier curves may be flattened to line segments due to numerical instability of doing bezier curve intersections.

    This function was introduced in Qt 4.3.
    How do I fix this?

  6. #5
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Changing a QGraphicsItem's transparency as a whole

    Bumped topic

Similar Threads

  1. QSlider: changing the groove without changing the handle
    By Olivier Berten in forum Qt Programming
    Replies: 3
    Last Post: 30th April 2013, 10:02
  2. Replies: 7
    Last Post: 29th November 2010, 19:20
  3. Replies: 2
    Last Post: 10th August 2009, 09:45
  4. Transparency ... Again
    By EricF in forum Qt Programming
    Replies: 4
    Last Post: 1st December 2007, 19:52
  5. transparency
    By roms18 in forum Qt Programming
    Replies: 2
    Last Post: 16th February 2006, 19:38

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.