Отрисовка текста в QRect

168
25 февраля 2019, 10:20

Есть окно с кастовыми диаграммами, в котором можно менять шаг сетки по времени и масштаб в пикселях: После каждого изменения происходит перерисовка диаграммы. Шкала времени и сама диаграмма — 2 разных виджета, помещённых на два разных скрола.

Задача: рисовать подпись вертикальных линий центрировано, и чтобы никто ни на кого не налезал.

Здесь же, на SO, подглядел решение, что можно узнать, сколько в пикселях будет занимать текст. А значит можно взять размер максимальной подписи и танцевать уже от него:

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))); 

Сама перерисовка шкалы с подписями:

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)));
    }

Проблема: почему-то возникают ситуации, когда числа (например, 5229 у верхней диаграммы) не влазят в свой QRect и происходит небольшое обрезание отображаемого.

Answer 1

Решил проблему добавлением запаса к размеру QRect:

//  Функция отрисовки шкалы
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)));
}
READ ALSO
Выход из цикла ввода при нажатии кнопки enter

Выход из цикла ввода при нажатии кнопки enter

Как сделать выход из цикла при нажатии кнопки enter?

135
Не работает скроллинг у QWidget

Не работает скроллинг у QWidget

Есть окно с кастомными виджетами-диаграммами и виджетами-временным-шкалами: Изначально размер виджета-диграммы задаётся в конструкторе...

131
Перевод функции на MASM в C++

Перевод функции на MASM в C++

Учу C++ и разбирая один проект наткнулся на то что автор часть функций (основных) реализовал на MASM, а очень плохо разбираюсь в MASM, и в интернете...

169
Вызов метода одного потока из другого

Вызов метода одного потока из другого

У меня есть функция которая вызывается отдельным потоком и поток отделяется:

136