There is a window with caste diagrams in which you can change the grid spacing in time and scale in pixels: Digram window After each change, the diagram is redrawn. The time scale and the chart itself are 2 different widgets placed on two different scrolls.

The task: to draw the signature of the vertical lines is centered, and so that no one climbs on anyone.

Here, on SO, I looked at the decision that you can find out how much the pixels will occupy the text. So you can take the size of the maximum signature and dance from him already:

lastNumber = static_cast<unsigned int>(dialog->commonSAGridSpacing * width() / dialog->commonSAScale); QFont currentFont = _painter->font(); QFontMetrics fm(currentFont); unsigned int size = static_cast<unsigned int>(fm.width(QString::number(lastNumber))); 

The scale itself is redrawn with captions:

 unsigned int maxNumberSizePix = numbersSizePix(painter); unsigned int separatorPX = 4; unsigned int shift = (maxNumberSizePix + separatorPX) / dialog->commonSAScale + 1; for (unsigned int counter = dialog->commonSAScale; counter < static_cast<unsigned int>(width()); counter += dialog->commonSAScale * shift) { QRectF currentRect(counter - maxNumberSizePix / 2, 2, maxNumberSizePix, height() - 4); painter->drawText(currentRect, Qt::AlignCenter, QString::number(static_cast<int>(counter / dialog->commonSAScale * dialog->commonSAGridSpacing))); } 

Problem: for some reason, there are situations when the numbers (for example, 5229 at the top of the diagram) do not fit into your QRect and a small trimming of the displayed one occurs.

  • I do not understand how you determine the size of the rectangle containing the label. Solved a similar problem for my widget 2D graphics rendering, there are a lot of pitfalls - Bearded Beaver
  • I think you did not take into account that in your font different numbers of the same length occupy a different number of pixels due to the difference in the size of numbers, kerning and ligatures ... the simplest and most reliable IMHO is to use monospace font ... otherwise - use the widest characters of the font to calculate how many you need pixels (for example, all eight) + 10% margin ... you can still see. how many take all the displayed numbers and choose the maximum ... and in any case it will be good to give drawText 'the entire rectangle with delimiters - IMHO the creeping numbers, of course, is also unpleasant. but better than cropped ... - Fat-Zer
  • @BeardedBeaver, I take the current font from painter, I consider the last number and measure it in pixels using the ready method - Arseniy Spiridonov
  • one
    how exactly do you consider the size in pixels? boundingRect? - goldstar_labs
  • @goldstar_labs, sorry, added the code. Through QFontMetrics - Arseniy Spiridonov

1 answer 1

Solved the problem by adding stock to QRect size:

 // Функция отрисовки шкалы void TimeScale::draw(QPainter *painter) { painter->setRenderHint(QPainter::NonCosmeticDefaultPen, true); QPen *pen = new QPen(Qt::black); pen->setWidth(1); painter->setPen(*pen); int maxNumberSizePix = static_cast<int>(1.15 * numbersSizePix(painter)); int separatorPX = 6; int scale; double gridSpacing; if (commonType) { scale = static_cast<int>(dialog->commonSAScale); gridSpacing = dialog->commonSAGridSpacing; } else { scale = static_cast<int>(dialog->resultsSAScale); gridSpacing = dialog->resultsSAGridSpacing; } int shift = static_cast<int>(1.0 * (maxNumberSizePix + separatorPX) / scale) + 1; for (int counter = scale; counter < width(); counter += scale * shift) { QRectF currentRect(counter - maxNumberSizePix / 2, 2, maxNumberSizePix, height() - 4); painter->drawText(currentRect, Qt::AlignCenter, QString::number(static_cast<int>(gridSpacing * counter / scale))); } delete pen; } // Размер последнего числа на шкале в пикселях unsigned int TimeScale::numbersSizePix(QPainter *_painter) { unsigned int lastNumber = 0; if (commonType) { lastNumber = static_cast<unsigned int>(dialog->commonSAGridSpacing * width() / dialog->commonSAScale); } else { lastNumber = static_cast<unsigned int>(dialog->resultsSAGridSpacing * width() / dialog->resultsSAScale); } QFont currentFont = _painter->font(); QFontMetrics fm(currentFont); return static_cast<unsigned int>(fm.width(QString::number(lastNumber))); }