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)
____________________________________
| | /\ vert. offset |
| | || Hour labels here |
| horiz. |___\/___________________|
| offset | |
|<-------->| Vertical hour lines |
| | here |
|__________|________________________|
____________________________________
| | /\ vert. offset |
| | || Hour labels here |
| horiz. |___\/___________________|
| offset | |
|<-------->| Vertical hour lines |
| | here |
|__________|________________________|
To copy to clipboard, switch view to plain text mode
The hour lines and labels are like this
________________________________________________
| 00:00 01:00 02:00 03:00
| horiz. | |<-------->| |
| offset | | hour | |
| | | offset | |
|__________|__________|__________|__________|___
________________________________________________
| 00:00 01:00 02:00 03:00
| horiz. | |<-------->| |
| offset | | hour | |
| | | offset | |
|__________|__________|__________|__________|___
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:
void ShiftScene
::drawBackground(QPainter *painter,
const QRectF
& rect
) {
//vertOffset: constant of type double representing the vertical space at the top of the graph reservet for hour labels (Top margin)
//hourOffset: constant of type double representig the space (horizontal) between two hour lines (vertical lines).
//horizOffset: constant of type double representing the left margin. The first hour (00:00) should be at x = horizOffset
//following hours should be at x = horizOffset + hourOffset * N (where N is between 0 and 24)
const qreal x1 = rect.left();
const qreal x2 = rect.right();
const qreal t = qMax(rect.top(), vertOffset); //Don't draw lines in vertOffset space, leave it for the labels
const qreal b = rect.bottom();
if(t > b)
return;
qDebug() << x1 << x2;
int f = qFloor((x1 - horizOffset) / hourOffset);
qreal fx = f * hourOffset + horizOffset;
if(f < 0.0)
{
f = 0.0;
fx = horizOffset;
}
if(fx < x1)
{
f += 1;
fx += hourOffset;
}
int l = qFloor((x2 - horizOffset) / hourOffset);
qreal lx = l * hourOffset + horizOffset;
if(l > 25.0)
{
l = 25.0;
lx = 25.0 * hourOffset + horizOffset;
}
if(lx > x2)
{
l -= 1;
lx -= hourOffset;
}
if(f > l)
return;
qDebug() << " First:" << f << "Last:" << l;
qDebug() << " " << fx << lx;
if(true)
{
painter->setPen(Qt::blue);
painter
->setFont
(QFont("ARIAL",
10,
QFont::Bold));
const QString fmt
= QStringLiteral
("%1:00");
double huorX = horizOffset;
for(int i = 0; i < 25; i++)
{
qDebug() << "Shift Hour:" << i << "X:" << huorX << horizOffset << hourOffset;
painter
->drawText
(QPointF(huorX,
15), fmt.
arg(i
));
huorX += hourOffset;
}
}
size_t n = size_t(l - f + 1);
double lineX = fx;
for(std::size_t i = 0; i < n; i++)
{
arr
[i
] = QLineF(lineX, t, lineX, b
);
lineX += hourOffset;
}
painter->setPen(linePen);
painter->drawLines(arr, int(n));
delete [] arr;
}
void ShiftScene::drawBackground(QPainter *painter, const QRectF& rect)
{
//vertOffset: constant of type double representing the vertical space at the top of the graph reservet for hour labels (Top margin)
//hourOffset: constant of type double representig the space (horizontal) between two hour lines (vertical lines).
//horizOffset: constant of type double representing the left margin. The first hour (00:00) should be at x = horizOffset
//following hours should be at x = horizOffset + hourOffset * N (where N is between 0 and 24)
const qreal x1 = rect.left();
const qreal x2 = rect.right();
const qreal t = qMax(rect.top(), vertOffset); //Don't draw lines in vertOffset space, leave it for the labels
const qreal b = rect.bottom();
if(t > b)
return;
qDebug() << x1 << x2;
int f = qFloor((x1 - horizOffset) / hourOffset);
qreal fx = f * hourOffset + horizOffset;
if(f < 0.0)
{
f = 0.0;
fx = horizOffset;
}
if(fx < x1)
{
f += 1;
fx += hourOffset;
}
int l = qFloor((x2 - horizOffset) / hourOffset);
qreal lx = l * hourOffset + horizOffset;
if(l > 25.0)
{
l = 25.0;
lx = 25.0 * hourOffset + horizOffset;
}
if(lx > x2)
{
l -= 1;
lx -= hourOffset;
}
if(f > l)
return;
qDebug() << " First:" << f << "Last:" << l;
qDebug() << " " << fx << lx;
if(true)
{
painter->setPen(Qt::blue);
painter->setFont(QFont("ARIAL", 10, QFont::Bold));
const QString fmt = QStringLiteral("%1:00");
double huorX = horizOffset;
for(int i = 0; i < 25; i++)
{
qDebug() << "Shift Hour:" << i << "X:" << huorX << horizOffset << hourOffset;
painter->drawText(QPointF(huorX, 15), fmt.arg(i));
huorX += hourOffset;
}
}
size_t n = size_t(l - f + 1);
QLineF *arr = new QLineF[n];
double lineX = fx;
for(std::size_t i = 0; i < n; i++)
{
arr[i] = QLineF(lineX, t, lineX, b);
lineX += hourOffset;
}
painter->setPen(linePen);
painter->drawLines(arr, int(n));
delete [] arr;
}
To copy to clipboard, switch view to plain text mode
Thanks in advance
Bookmarks