Results 1 to 7 of 7

Thread: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

  1. #1
    Join Date
    May 2012
    Posts
    4
    Thanks
    1
    Qt products
    Qt4

    Default Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    I'm experiencing a strange problem in my application. I'm using a QGraphicsView along with a QGraphicsScene to display items. Some of the items have special tooltips which appear when the mouse hovers on top of them.

    step1.png

    The tooltips inherit QGraphicsTextItem in order to provide a border, margin, and custom background. Also, some of the items, which are children to the item with the current tooltip, also display a tooltip of their own when hovered.

    step2.png

    And now to the problem: When the second tooltip is removed (by moving the mouse out of the child item), the text of the first tooltip is cropped.

    step3.png

    This doesn't always happen but very often when the tooltips are displayed and then removed. Moreover, the same things sometimes happens even when there is no second tooltip over it. First I suspected this had something to do with the antialiasing, but deactivating it didn't remove the symptoms. I've provided a minimal working example below to isolate the problem.

    Qt Code:
    1. #include <QApplication>
    2. #include <QGraphicsItem>
    3. #include <QGraphicsRectItem>
    4. #include <QGraphicsScene>
    5. #include <QGraphicsSceneHoverEvent>
    6. #include <QGraphicsTextItem>
    7. #include <QGraphicsView>
    8. #include <QMainWindow>
    9. #include <QPainter>
    10. #include <QPointF>
    11. #include <QRectF>
    12. #include <QSizeF>
    13. #include <QString>
    14. #include <QStyleOptionGraphicsItem>
    15.  
    16. class ToolTipItem : public QGraphicsTextItem {
    17. public:
    18. ToolTipItem(const QString& text)
    19. {
    20. setAcceptHoverEvents(true);
    21. }
    22.  
    23. virtual ~ToolTipItem(void) {}
    24.  
    25. virtual QRectF boundingRect(void) const {
    26. QRectF rect(QPointF(0, 0), getSize());
    27. qreal d = BORDER_WIDTH / 2;
    28. rect.adjust(-d, -d, d, d);
    29. return rect;
    30. }
    31.  
    32. virtual void paint(
    33. QPainter* painter,
    34. QWidget* widget)
    35. {
    36. // Draw surrounding box
    37. painter->setPen(QPen(BORDER_COLOR, BORDER_WIDTH));
    38. painter->setBrush(QBrush(BACKGROUND_COLOR));
    39. QRectF rect(QPointF(0, 0), getSize());
    40. painter->drawRect(rect);
    41.  
    42. // Draw text content
    43. painter->translate(QPointF(MARGIN, MARGIN));
    44. QGraphicsTextItem::paint(painter, option, widget);
    45. }
    46.  
    47. virtual QPainterPath shape(void) const {
    48. path.addRect(boundingRect());
    49. return path;
    50. }
    51.  
    52. QSizeF getSize(void) const {
    53. QRectF rect(QGraphicsTextItem::boundingRect());
    54. rect.adjust(0, 0, 2*MARGIN, 2*MARGIN);
    55. return rect.size();
    56. }
    57.  
    58. void placeNextTo(QGraphicsItem* item) {
    59. QPointF item_point_in_scene =
    60. item->mapToScene(item->boundingRect().topLeft());
    61. qreal x_pos = item_point_in_scene.x() - boundingRect().size().width()
    62. + 1.5 * BORDER_WIDTH;
    63. qreal y_pos = item_point_in_scene.y() + BORDER_WIDTH / 2;
    64. QPointF tooltip_point_in_scene(x_pos, y_pos);
    65. setPos(tooltip_point_in_scene);
    66. }
    67.  
    68. protected:
    69. static const QColor BACKGROUND_COLOR;
    70. static const qreal MARGIN;
    71. static const qreal BORDER_WIDTH;
    72. static const QColor BORDER_COLOR;
    73. };
    74.  
    75. const QColor ToolTipItem::BACKGROUND_COLOR(Qt::white);
    76. const qreal ToolTipItem::MARGIN = 5;
    77. const qreal ToolTipItem::BORDER_WIDTH = 1;
    78. const QColor ToolTipItem::BORDER_COLOR(Qt::black);
    79.  
    80. class MyItem : public QGraphicsRectItem {
    81. public:
    82. MyItem(qreal x, qreal y, qreal width, qreal height,
    83. QGraphicsItem* parent = 0)
    84. : QGraphicsRectItem(x, y, width, height, parent),
    85. tooltip_(NULL)
    86. {
    87. setAcceptHoverEvents(true);
    88. }
    89.  
    90. virtual ~MyItem(void) {}
    91.  
    92.  
    93. protected:
    94. virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event) {
    95. event->accept();
    96. if (!tooltip_) {
    97. tooltip_ = new ToolTipItem("bla bla bla\nfadsf asdf\nfdasdfas");
    98. tooltip_->placeNextTo(this);
    99. scene()->addItem(tooltip_);
    100. }
    101. tooltip_->show();
    102. }
    103.  
    104. virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) {
    105. event->accept();
    106. if (tooltip_) tooltip_->hide();
    107. }
    108.  
    109. private:
    110. ToolTipItem* tooltip_;
    111. };
    112.  
    113.  
    114.  
    115. int main(int argc, char** argv) {
    116. QApplication app(argc, argv);
    117.  
    118. MyItem* item1 = new MyItem(0, 0, 50, 50);
    119. MyItem* item2 = new MyItem(20, 10, 10, 10, item1);
    120. MyItem* item3 = new MyItem(20, 20, 10, 10, item2);
    121. scene->addItem(item1);
    122.  
    123. QGraphicsView* view = new QGraphicsView(scene);
    124. view->setRenderHint(QPainter::Antialiasing);
    125. QMainWindow window;
    126. window.setCentralWidget(view);
    127. window.show();
    128.  
    129. return app.exec();
    130. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    May 2012
    Posts
    4
    Thanks
    1
    Qt products
    Qt4

    Default Re: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    No one has any idea on what's going on...?

  3. #3
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    Not sure, but it looks like some artifact left over from the translate. Try this instead:
    Qt Code:
    1. // Draw text content
    2. //painter->translate(QPointF(MARGIN, MARGIN));
    3. document()->setDocumentMargins(MARGIN);
    4. QGraphicsTextItem::paint(painter, option, widget);
    To copy to clipboard, switch view to plain text mode 
    Last edited by norobro; 10th May 2012 at 22:56.

  4. The following user says thank you to norobro for this useful post:

    ghb (11th May 2012)

  5. #4
    Join Date
    May 2012
    Posts
    4
    Thanks
    1
    Qt products
    Qt4

    Default Re: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    Interesting. Removing the translate() call actually fixes the problem!

    However, in my case, setDocumentMargin() does nothing, or at least the call has no effect. What can I do to add some margin between the border and the content without resorting to translate()?


    Added after 49 minutes:


    Wrapping the HTML text with a <div style="margin: MARGINpx"> ... </div> at least adds some margin to the sides, but for some reason it has no effect on the margin of the top or bottom. Strange... Well, it'll have to do; at least it looks better than before, and I no longer have those weird artefacts. Thanks for your help!
    Last edited by ghb; 11th May 2012 at 09:43.

  6. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    You can only paint within your own boundingRect(). If you paint outside it (like when using translate()), you will be getting artifacts.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. The following user says thank you to wysota for this useful post:

    norobro (11th May 2012)

  8. #6
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    Quote Originally Posted by ghb View Post
    However, in my case, setDocumentMargin() does nothing, or at least the call has no effect.
    Strange. Works here using your example.

    The docs say the default margin is 4 and you only use 5. Have you tried a larger value?
    Last edited by norobro; 11th May 2012 at 22:55. Reason: typo

  9. #7
    Join Date
    May 2012
    Posts
    4
    Thanks
    1
    Qt products
    Qt4

    Default Re: Parts of rendered QGraphicsTextItem text is destroyed by other scene items

    I believe I used a value of 10.

Similar Threads

  1. Text rendered as squares
    By SeppeVanNolle in forum Qt for Embedded and Mobile
    Replies: 4
    Last Post: 9th November 2011, 15:17
  2. Saving a FULLY rendered QWidget on a graphics scene
    By technoViking in forum Qt Programming
    Replies: 7
    Last Post: 25th October 2010, 22:47
  3. add items into scene
    By Noxxik in forum Qt Programming
    Replies: 0
    Last Post: 9th March 2009, 16:32
  4. Replies: 2
    Last Post: 24th January 2009, 18:30
  5. Can't move Items in the scene
    By maverick_pol in forum Qt Programming
    Replies: 2
    Last Post: 16th May 2008, 09:40

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.