Text is not appearing at specified position in Qt
-
I have a QGraphicsView which contains many QGraphicsItem like rectangle, polylines etc. I want to name each rectangle and name is on the rectangle.
Name should be centrally aligned i.e. half of the string name characters should be left side of mid position and half of the characters should be right side of mid position.
For that I used following psuedo code:int firstPosition = GetMidPosition () - (strLength / 2); int secondPosition = some points DrawText( firstPosition , secondPosition );
Now if I print co-ordinates of firstPosition, secondPosition , GetMidPosition() they comes perfectly as I expect.
But, the text does not come properly. I have to manually adjust it.int firstPosition = GetMidPosition () - 6 *(strLength / 2);
Now it appears centrally. Why this is happening ? Co-ordinates are correct then why I have to manually adjust it.
I want to avoid that adjustment (i.e. 6 * )If tomorrow, I changed the font size of text, then I will have to change the multiplication factor 6 into something else. That should not be happened. How to write general purpose logic for this ?
-
I have a QGraphicsView which contains many QGraphicsItem like rectangle, polylines etc. I want to name each rectangle and name is on the rectangle.
Name should be centrally aligned i.e. half of the string name characters should be left side of mid position and half of the characters should be right side of mid position.
For that I used following psuedo code:int firstPosition = GetMidPosition () - (strLength / 2); int secondPosition = some points DrawText( firstPosition , secondPosition );
Now if I print co-ordinates of firstPosition, secondPosition , GetMidPosition() they comes perfectly as I expect.
But, the text does not come properly. I have to manually adjust it.int firstPosition = GetMidPosition () - 6 *(strLength / 2);
Now it appears centrally. Why this is happening ? Co-ordinates are correct then why I have to manually adjust it.
I want to avoid that adjustment (i.e. 6 * )If tomorrow, I changed the font size of text, then I will have to change the multiplication factor 6 into something else. That should not be happened. How to write general purpose logic for this ?
-
I have a QGraphicsView which contains many QGraphicsItem like rectangle, polylines etc. I want to name each rectangle and name is on the rectangle.
Name should be centrally aligned i.e. half of the string name characters should be left side of mid position and half of the characters should be right side of mid position.
For that I used following psuedo code:int firstPosition = GetMidPosition () - (strLength / 2); int secondPosition = some points DrawText( firstPosition , secondPosition );
Now if I print co-ordinates of firstPosition, secondPosition , GetMidPosition() they comes perfectly as I expect.
But, the text does not come properly. I have to manually adjust it.int firstPosition = GetMidPosition () - 6 *(strLength / 2);
Now it appears centrally. Why this is happening ? Co-ordinates are correct then why I have to manually adjust it.
I want to avoid that adjustment (i.e. 6 * )If tomorrow, I changed the font size of text, then I will have to change the multiplication factor 6 into something else. That should not be happened. How to write general purpose logic for this ?
@tushu said in Text is not appearing at specified position in Qt:
Co-ordinates are correct then why I have to manually adjust it.
Because strLength only says how many characters the string contains, it says nothing about the space the string needs to be shown (it depends on font size and font). You will need to use https://doc.qt.io/qt-5/qfontmetrics.html to calculate the space a string needs to be shown.
-
@tushu said in Text is not appearing at specified position in Qt:
Co-ordinates are correct then why I have to manually adjust it.
Because strLength only says how many characters the string contains, it says nothing about the space the string needs to be shown (it depends on font size and font). You will need to use https://doc.qt.io/qt-5/qfontmetrics.html to calculate the space a string needs to be shown.
@jsulm Thank you for your reply.
I have done following way :QFont defaultFont = QApplication::font(); QFontMetrics f = QFontMetrics(defaultFont); QRect r = f.boundingRect("Checker"); int w = r.width()/4; int firstPosition = GetMidPosition () - w;
But still I have to divide width by 4. ( r.width()/4 ) ( then and then only it gives proper text position )
Am I right ? -
@jsulm Thank you for your reply.
I have done following way :QFont defaultFont = QApplication::font(); QFontMetrics f = QFontMetrics(defaultFont); QRect r = f.boundingRect("Checker"); int w = r.width()/4; int firstPosition = GetMidPosition () - w;
But still I have to divide width by 4. ( r.width()/4 ) ( then and then only it gives proper text position )
Am I right ? -
@tushu
My math/logic tells me I would expect to usewidth / 2
rather than/ 4
to subtract from the mid position (assumingGetMidPosition()
code is right) in order to find the left position...? -
@JonB Yes you are right. I tried width / 2 but text position was not correct. So I tried width/4 and the position got correct.
Am I right ?@tushu said in Text is not appearing at specified position in Qt:
Am I right ?
Logically, not to my understanding...
So I tried width/4 and the position got correct.
...but I cannot argue with empirical evidence!
:)
Do you want to paste what your
GetMidPosition()
is actually doing...? -
@tushu said in Text is not appearing at specified position in Qt:
Am I right ?
Logically, not to my understanding...
So I tried width/4 and the position got correct.
...but I cannot argue with empirical evidence!
:)
Do you want to paste what your
GetMidPosition()
is actually doing...?@JonB Thank you for your concern and help.
I would love to paste the code, but it will be very hard to understand as it is not straightforward. It uses tuple in c++, other class's function. And main thing is I have not written that code ( that's routing part and I am on rendering side) I am just using that function so It will be very hard to explain you.Sorry for this doubt but I have to ask.
Currently in my design, there are multiple polylines and rectangles. But some of the polylines are such that, If I try to select any polyline, I could not select them but some other polyline gets selected. But If I remove that other selected polyline then I can select my desired polyline. ( I have a hide polyline feature )Now I do not know how to proceed with this let alone finding solution. I am clueless. How to think ? How to debug this issue ?
Can you help me ? -
@JonB Thank you for your concern and help.
I would love to paste the code, but it will be very hard to understand as it is not straightforward. It uses tuple in c++, other class's function. And main thing is I have not written that code ( that's routing part and I am on rendering side) I am just using that function so It will be very hard to explain you.Sorry for this doubt but I have to ask.
Currently in my design, there are multiple polylines and rectangles. But some of the polylines are such that, If I try to select any polyline, I could not select them but some other polyline gets selected. But If I remove that other selected polyline then I can select my desired polyline. ( I have a hide polyline feature )Now I do not know how to proceed with this let alone finding solution. I am clueless. How to think ? How to debug this issue ?
Can you help me ? -
Hi,
Any chances you have a scale factor applied to the screen you are working on ?
-
- Without seeing snippets of relevant code how can anybody help you?
- Step through the code in a debugger to see how it is behaving.
@JonB @SGaist @jsulm It's a continuation of my last question to you (i.e. If I try to select a particular polyline , it does not get select but some other polyline gets selected.
Here is my design
If I click on position A , B, C , D orange color polyline gets selected. If I try to select polyline inside U - shaped orange polyline, they never get selected. Only the orange color polyline gets selected.
If I click on position E, F, G a blue color polyline gets selected. I can not select anything which is inside of these U - shaped polylines. If I try to select anything inside these U - shaped polylines, only U shaped polyline gets selected.
There are many polylines and rectangles in the design. But this problem arises with only U - shaped polylines. Other polylines ( which are not U shape, and which are not inside U - shaped polylines get selected properly. )
Now come to the coding part:
There is a by default Qt's selection method of any QGraphicsItem. If you click on them, it creates a dotted rectangle around that item. So, in U shape polylines, it creates a rectangle and if you click inside that rectangle, that polyline gets selected.
In paint() method I have changed the selection method of Qt, but I think there is still a problemvoid myPoly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { auto copied_option = *option; copied_option.state &= ~QStyle::State_Selected; auto selected = option->state & QStyle::State_Selected; QGraphicsPathItem::paint(painter, &copied_option, widget); if (selected) { painter->save(); painter->setBrush(Qt::NoBrush); painter->setPen(QPen(option->palette.windowText(), 0, Qt::SolidLine)); painter->drawPath(shape()); painter->restore(); } }
-
@JonB @SGaist @jsulm It's a continuation of my last question to you (i.e. If I try to select a particular polyline , it does not get select but some other polyline gets selected.
Here is my design
If I click on position A , B, C , D orange color polyline gets selected. If I try to select polyline inside U - shaped orange polyline, they never get selected. Only the orange color polyline gets selected.
If I click on position E, F, G a blue color polyline gets selected. I can not select anything which is inside of these U - shaped polylines. If I try to select anything inside these U - shaped polylines, only U shaped polyline gets selected.
There are many polylines and rectangles in the design. But this problem arises with only U - shaped polylines. Other polylines ( which are not U shape, and which are not inside U - shaped polylines get selected properly. )
Now come to the coding part:
There is a by default Qt's selection method of any QGraphicsItem. If you click on them, it creates a dotted rectangle around that item. So, in U shape polylines, it creates a rectangle and if you click inside that rectangle, that polyline gets selected.
In paint() method I have changed the selection method of Qt, but I think there is still a problemvoid myPoly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { auto copied_option = *option; copied_option.state &= ~QStyle::State_Selected; auto selected = option->state & QStyle::State_Selected; QGraphicsPathItem::paint(painter, &copied_option, widget); if (selected) { painter->save(); painter->setBrush(Qt::NoBrush); painter->setPen(QPen(option->palette.windowText(), 0, Qt::SolidLine)); painter->drawPath(shape()); painter->restore(); } }
-
@tushu said in Text is not appearing at specified position in Qt:
Name should be centrally aligned i.e. half of the string name characters should be left side of mid position and half of the characters should be right side of mid position.
The width of each rendered character is variable unless you are using a monospace font (not normally the case). That is, an "e" takes fewer pixels horizontally than a "C". The Qt functions for sizing text work in the rendered pixel width not characters. You can position text to balance the number of pixels trivially (see examples below)
To get an even number of characters left/right of a line you would need to handle odd/even string lengths differently.
In the even case, divide the string into two, size and position each separately adjacent to the centre line.
In the odd case, split the string into three parts; left, right, and the centre character. Size and place the centre character (by pixel?), then size and place left/right parts to adjoin the centre character's bounding box.
This approach may have potential oddities associated with the whitespace between characters.include <QApplication> #include <QPixmap> #include <QPainter> #include <QFont> #include <QFontMetrics> #include <QDebug> int main(int argc, char **argv) { QApplication app(argc, argv); const QString text("Checker"); QPixmap pixmap(799, 799); pixmap.fill(); QPainter painter(&pixmap); QFont font("times", 20); painter.setFont(font); // Box we will centre on QRect tile(100, 100, 599, 599); painter.setPen(Qt::blue); painter.drawRect(tile); painter.setPen(Qt::gray); painter.drawLine(tile.center().x(), tile.top(), tile.center().x(), tile.bottom()); // text centred one way QFontMetrics f(font); QRect r = f.boundingRect(text); r.translate(tile.center().x() - r.width()/2, tile.top()); painter.setPen(Qt::red); painter.drawRect(r); painter.setPen(Qt::black); painter.drawText(r, text); // Using the painter to do the work painter.drawText(tile, Qt::AlignHCenter|Qt::AlignTop, text, &r); painter.setPen(Qt::green); painter.drawRect(r); painter.end(); pixmap.save("result.png"); return 0; }
-
@tushu said in Text is not appearing at specified position in Qt:
Name should be centrally aligned i.e. half of the string name characters should be left side of mid position and half of the characters should be right side of mid position.
The width of each rendered character is variable unless you are using a monospace font (not normally the case). That is, an "e" takes fewer pixels horizontally than a "C". The Qt functions for sizing text work in the rendered pixel width not characters. You can position text to balance the number of pixels trivially (see examples below)
To get an even number of characters left/right of a line you would need to handle odd/even string lengths differently.
In the even case, divide the string into two, size and position each separately adjacent to the centre line.
In the odd case, split the string into three parts; left, right, and the centre character. Size and place the centre character (by pixel?), then size and place left/right parts to adjoin the centre character's bounding box.
This approach may have potential oddities associated with the whitespace between characters.include <QApplication> #include <QPixmap> #include <QPainter> #include <QFont> #include <QFontMetrics> #include <QDebug> int main(int argc, char **argv) { QApplication app(argc, argv); const QString text("Checker"); QPixmap pixmap(799, 799); pixmap.fill(); QPainter painter(&pixmap); QFont font("times", 20); painter.setFont(font); // Box we will centre on QRect tile(100, 100, 599, 599); painter.setPen(Qt::blue); painter.drawRect(tile); painter.setPen(Qt::gray); painter.drawLine(tile.center().x(), tile.top(), tile.center().x(), tile.bottom()); // text centred one way QFontMetrics f(font); QRect r = f.boundingRect(text); r.translate(tile.center().x() - r.width()/2, tile.top()); painter.setPen(Qt::red); painter.drawRect(r); painter.setPen(Qt::black); painter.drawText(r, text); // Using the painter to do the work painter.drawText(tile, Qt::AlignHCenter|Qt::AlignTop, text, &r); painter.setPen(Qt::green); painter.drawRect(r); painter.end(); pixmap.save("result.png"); return 0; }
-
I assume your "polyline" is a custom derivative of QGraphicsItem. What happens if you setBoundingRegionGranularity() to something other than 0 so that your item returns something better than the default bounding box.
-
I assume your "polyline" is a custom derivative of QGraphicsItem. What happens if you setBoundingRegionGranularity() to something other than 0 so that your item returns something better than the default bounding box.
@ChrisW67
I tried what you said, but it did not work.
Here is my implementation for polyline.QPolygonF net; net << QPointF(67,202); net << QPointF(139,198); QPainterPath pPath; pPath.addPolygon(net); MyPoly* _poly = new MyPoly(); _poly->DrawPolyline(pPath); scene->addItem(static_cast<QGraphicsPathItem*>(_poly)); void MyPoly::DrawPolyline(QPainterPath pPath) { //this->setPen(QPen(QColor("red", 1)); this->setPath(pPath); this->setFlag(QGraphicsItem::ItemIsSelectable); this->setBoundingRegionGranularity(1); }