Results 1 to 3 of 3

Thread: QGraphicsScene background glitches

  1. #1
    Join Date
    Mar 2020
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default QGraphicsScene background glitches

    Hi,
    I'm new to this forum so please forgive me if this is not the right section.

    I'm trying to draw a background grid in which vertical lines represent hours.
    On top of this lines I draw the labels for each hour, like: '00:00' '01:00' '02:00' and so on.
    I previously created a QGraphicsLineItem for each hour and a QGraphicsSimpleTextItem for its label but that solution wasn't very efficent. Everytime the sceneRect resized I had to manually extend all line items and the sceneRect couldn't get smaller automatically because of theese vertical line items.

    Instead now I'm trying to achieve the same results by overriding QGraphicsScene::drawBackground().
    When the window containing the QGraphicsView is created everithing is fine but when I start scrolling the scene the hour labels are not drawn.
    The vertical lines instead work well.

    horizOffset represents Left margin width.
    vertOffset represent Top margin height (Left margin rect extends to the top)
    Qt Code:
    1. ____________________________________
    2. | | /\ vert. offset |
    3. | | || Hour labels here |
    4. | horiz. |___\/___________________|
    5. | offset | |
    6. |<-------->| Vertical hour lines |
    7. | | here |
    8. |__________|________________________|
    To copy to clipboard, switch view to plain text mode 
    The hour lines and labels are like this
    Qt Code:
    1. ________________________________________________
    2. | 00:00 01:00 02:00 03:00
    3. | horiz. | |<-------->| |
    4. | offset | | hour | |
    5. | | | offset | |
    6. |__________|__________|__________|__________|___
    To copy to clipboard, switch view to plain text mode 
    Qt Version: 5.11.3 kit
    Compiler: MinGW 32 bit
    OS: Windows 8.1 64 bit
    Here is my reimplemented function of QGraphicsScene:
    Qt Code:
    1. void ShiftScene::drawBackground(QPainter *painter, const QRectF& rect)
    2. {
    3. //vertOffset: constant of type double representing the vertical space at the top of the graph reservet for hour labels (Top margin)
    4. //hourOffset: constant of type double representig the space (horizontal) between two hour lines (vertical lines).
    5. //horizOffset: constant of type double representing the left margin. The first hour (00:00) should be at x = horizOffset
    6. //following hours should be at x = horizOffset + hourOffset * N (where N is between 0 and 24)
    7.  
    8. const qreal x1 = rect.left();
    9. const qreal x2 = rect.right();
    10. const qreal t = qMax(rect.top(), vertOffset); //Don't draw lines in vertOffset space, leave it for the labels
    11. const qreal b = rect.bottom();
    12.  
    13. if(t > b)
    14. return;
    15.  
    16. qDebug() << x1 << x2;
    17.  
    18. int f = qFloor((x1 - horizOffset) / hourOffset);
    19. qreal fx = f * hourOffset + horizOffset;
    20.  
    21. if(f < 0.0)
    22. {
    23. f = 0.0;
    24. fx = horizOffset;
    25. }
    26.  
    27. if(fx < x1)
    28. {
    29. f += 1;
    30. fx += hourOffset;
    31. }
    32.  
    33. int l = qFloor((x2 - horizOffset) / hourOffset);
    34. qreal lx = l * hourOffset + horizOffset;
    35.  
    36. if(l > 25.0)
    37. {
    38. l = 25.0;
    39. lx = 25.0 * hourOffset + horizOffset;
    40. }
    41.  
    42. if(lx > x2)
    43. {
    44. l -= 1;
    45. lx -= hourOffset;
    46. }
    47.  
    48. if(f > l)
    49. return;
    50.  
    51. qDebug() << " First:" << f << "Last:" << l;
    52. qDebug() << " " << fx << lx;
    53.  
    54. if(true)
    55. {
    56. painter->setPen(Qt::blue);
    57. painter->setFont(QFont("ARIAL", 10, QFont::Bold));
    58.  
    59. const QString fmt = QStringLiteral("%1:00");
    60. double huorX = horizOffset;
    61. for(int i = 0; i < 25; i++)
    62. {
    63. qDebug() << "Shift Hour:" << i << "X:" << huorX << horizOffset << hourOffset;
    64. painter->drawText(QPointF(huorX, 15), fmt.arg(i));
    65. huorX += hourOffset;
    66. }
    67. }
    68.  
    69. size_t n = size_t(l - f + 1);
    70. QLineF *arr = new QLineF[n];
    71. double lineX = fx;
    72. for(std::size_t i = 0; i < n; i++)
    73. {
    74. arr[i] = QLineF(lineX, t, lineX, b);
    75. lineX += hourOffset;
    76. }
    77.  
    78. painter->setPen(linePen);
    79. painter->drawLines(arr, int(n));
    80. delete [] arr;
    81. }
    To copy to clipboard, switch view to plain text mode 

    Thanks in advance
    Last edited by gfgit; 14th March 2020 at 16:09.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsScene background glitches

    Have not looked in detail at your code, but one things stands out: Allocating the QLineF arrays every time you draw the background (line 70 in your code). This will eventually really fragment memory and could cause your program to crash when the memory manager can't find enough for the next allocation.

    So instead of creating the array on the heap (with "new"), just allocate it on the stack:

    Qt Code:
    1. size_t n = size_t(l - f + 1);
    2. QVector< QLineF > arr( n );
    3. double lineX = fx;
    4. for(std::size_t i = 0; i < n; i++)
    5. {
    6. arr[i] = QLineF(lineX, t, lineX, b);
    7. lineX += hourOffset;
    8. }
    9.  
    10. painter->setPen(linePen);
    11. painter->drawLines( &(arr[0]), int(n));
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Mar 2020
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsScene background glitches

    But the array is not permanent, it's deleted right after drawing in line 80.
    QVector uses ::malloc() to allocate memory so it's always heap.


    Added after 5 minutes:


    I found the solution!
    It's quite simple.
    The proble with scrolling is that if the label text doesn't fit:
    Qt Code:
    1. +-----------+
    2. | te|xt
    3. | |
    4. +-----------+
    To copy to clipboard, switch view to plain text mode 
    In this case (word 'text') the first 2 characters ('te') are drawn on the viewport while the last 2 are not drawn ('xt') because they don't fit.
    When scrolling a bit to the right (viewport moves to the left) the result should be this:
    Qt Code:
    1. +-----------+
    2. | tex|t
    3. | |
    4. +-----------+
    To copy to clipboard, switch view to plain text mode 
    I think considered the label as 'already finished drawing' even if only a part of it was painted and didn't draw again the rest (previously hidden, now visible).
    So the label remains truncated until you refresh the entire window (for example hide and then show again) The result was this:
    Qt Code:
    1. +-----------+
    2. | te |
    3. | |
    4. +-----------+
    To copy to clipboard, switch view to plain text mode 
    The solution is to remove this code: (from line 27 to line 31)
    Qt Code:
    1. if(fx < x1)
    2. {
    3. f += 1;
    4. fx += hourOffset;
    5. }
    To copy to clipboard, switch view to plain text mode 
    Removing this lines you also redraw the line before the first new line to draw because the line itself is thin so it's probably out of the new rect to paint but the label is long (wide) so the last part of the text might be in the new area and must be painted again.

    I also removed the following part but I noticed that even without removing it the problem is not present anymore: (from line 42 to line 46)
    Qt Code:
    1. if(lx > x2)
    2. {
    3. l -= 1;
    4. lx -= hourOffset;
    5. }
    To copy to clipboard, switch view to plain text mode 

    Hope it helps!

    EDIT:
    How do I mark this thread as SOLVED ?
    Last edited by gfgit; 14th March 2020 at 19:12.

Similar Threads

  1. QGraphicsScene background glitches
    By gfgit in forum Qt Programming
    Replies: 0
    Last Post: 14th March 2020, 14:14
  2. QGraphicsScene QPixmap background
    By twells5 in forum Qt Programming
    Replies: 1
    Last Post: 4th June 2016, 23:19
  3. QgraphicsScene on QGLWidget background
    By ksrini in forum Qt Programming
    Replies: 2
    Last Post: 30th October 2009, 10:57
  4. Flashing cursor causes graphical glitches in the GUI
    By gboelter in forum Qt Programming
    Replies: 0
    Last Post: 29th October 2009, 04:48
  5. QGraphicsScene background
    By goldhappywang in forum Newbie
    Replies: 2
    Last Post: 28th April 2009, 08:57

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.