Solved drawing text with monospace font not giving the same bounding rect (Qt 5.13.2)
-
I would check textSize instead boundingRect since the boudingRect is the real width needed afaiu.
-
Ok good point. I would expect those 2 values to be equivalent (especially for monospace fonts...).
I did add textSize to my qDebug statement, in my case, they seem to be the same:
qDebug() << txt.size() << boundingRect << textSize;
family Source Code Pro px: 11 77 QRectF(0,0 530x17) QSize(530, 17) 77 QRectF(0,0 530x17) QSize(530, 17) 77 QRectF(0,0 530x17) QSize(530, 17) 77 QRectF(0,0 530x17) QSize(530, 17) 77 QRectF(0,0 518x17) QSize(518, 17) 77 QRectF(0,0 530x17) QSize(530, 17) 77 QRectF(0,0 530x17) QSize(530, 17) 77 QRectF(0,0 526x17) QSize(526, 17)
Ok, I guess it is time to read some good QPainter::drawText() code... I tried to avoid this but it seems to be the only way to figure out....
Update: There is no way that I'm going to hunt this bug down inside Qt guts. I did put my nose into QTextEngine code and this beast is monstrously complex...
I did play with:
QString("%1").arg(val, 5, 'f', 2);
by changing the fill character.... I don't understand anymore what monospace mean. This is the root of my problem. If I pick 'a', 'A' or '.' (dot) as the fill character, the issue is still present... BUT if I choose '0' (zero). The boundingRect becomes rock solid and stable for all my strings.
-
Monospace means that every character has the same width and height - for example 8x14 pixels. This means no other character will be drawn inside this rect. It does not mean that all character will fill the 8x14 pixel - some will only fill e.g. 2x13 (e.g. an 'i'), some maybe 8x12 (e.g. 'w') - and this is why you get back different widths for the bounding rect.
-
Christian, I would agree if the bouding rect width difference was due to only the trailing character and I wouldn't care.
This is a string that is updated based on mouse cursor position and the width difference occurs almost at the beginning of the string. This makes monitoring it almost as sickening as being rocked while in a boat during a big storm...
Beside, I don't get it. If I take any text editor, open any file from a terminal with vi or emacs. The 79th character will always be aligned with all the other lines's 79th character no matter what is the text content. I can even achieve this with LibreOffice Writer when I use a monospace font.
Why can't I with Qt? Why would it be different?
-
@lano1106 said in drawing text with monospace font not giving the same bounding rect (Qt 5.13.2):
The 79th character will always be aligned with all the other lines's 79th character no matter what is the text content
This is also true for Qt - otherwise you qtcreator would not work. I would guess QPainter::drawText() is given a wrong rectangle and therefore it's jumping. I would use the QPointF version. Also please provide a minimal compilable example so we can debug your problem.
-
Christian,
thanks a lot for your support. I'm trying to nail down the issue. Right now, I have a small program and this one gives me the correct behavior. I will build up from there until I'm able to reproduce the issue.
monospace.h:
#include <QWidget> class MonospaceIssue : public QWidget { Q_OBJECT public: MonospaceIssue(QWidget *parent = NULL); virtual ~MonospaceIssue(); protected: virtual void paintEvent(QPaintEvent *event); };
main.cpp:
#include <QApplication> #include <QPainter> #include "monospace.h" MonospaceIssue::MonospaceIssue(QWidget *parent) : QWidget(parent) { } MonospaceIssue::~MonospaceIssue() { } void MonospaceIssue::paintEvent(QPaintEvent *event) { QPainter painter(this); QFont monoFont("Source Code Pro", 8); painter.setFont(monoFont); QPen magentaPen = QPen(QColor(Qt::magenta), 1); painter.setPen(magentaPen); QString shouldHaveSameWidthTxt = "WWWWWWWWWWW 27.87aaaaa 10.88Ecmd\n" "iiiiiiiiiii 7,14MMMMM 7.66Ecmd"; QFontMetrics metrics(monoFont); QSize textSize = metrics.size(0, shouldHaveSameWidthTxt); QRectF boundingRect; painter.drawText(QRectF(QPointF(0,0), textSize), Qt::AlignLeft|Qt::AlignVCenter, shouldHaveSameWidthTxt, &boundingRect); } int main(int argc, char *argv[]) { QApplication app(argc, argv); MonospaceIssue MyWindow; MyWindow.show(); return app.exec(); }
stay tuned.
-
Maybe add a variable string for your painting by e.g enable mouse tracking and print out the mouse positions.
-
Not necessary. I did just plug in the crafted string literal into my application. This is obviously not monospace that I am getting.
I will simplify things until I isolate the issue.
Simple test program output:
Application output:
Almost there...
-
Ok. I am ashamed.... When I get stupid problems like this one... It means that I start to be tired and should look at it back the next morning... I have found my problem. The problem is all good. There was a crucial missing line in my code:
void LinkedChart::setInfoText(const QString &text) { if (text == m_text) return; m_text = text; if (!m_textItem) { if (!text.size()) return; // m_textItem = scene()->addSimpleText(text, m_textFont); m_textItem = new StupidSimpleText(text); scene()->addItem(m_textItem); QPen magentaPen = QPen(QColor(Qt::magenta), 1); m_textItem->setPen(magentaPen); m_textItem->setFont(m_textFont); // <<<----- I omitted to set my super duper monospace font in the Graphics Item QPointF plotTopLeft = plotArea().topLeft(); plotTopLeft.rx() += 5.0; plotTopLeft.ry() += 5.0; m_textItem->setPos(plotTopLeft); /* * Connection to reposition the graphics item when/if the plotarea is changing. */ connect(this, SIGNAL(plotAreaChanged(const QRectF &)), this, SLOT(ourPlotAreaChanged(const QRectF &))); } m_textItem->setText(text); }
-
Nice to see the problem solved :)