19

is there a way to draw fixed text that has subscripts. My goal is to have something like: "K_max=K_2 . 3"

QString equation="K_max=K_2 . 3";
painter.drawText( QRect(x, y , width, y+height), Qt::AlignLeft|Qt::AlignVCenter, equation);

I also tried formatting the text using html tags but it didn't help (tags got printed with the text):

QString equation="<p>K<sub>max</sub></p>=<p>K<sub>2</sub></p>.3"
UmNyobe
  • 22,539
  • 9
  • 61
  • 90
luffy
  • 2,246
  • 3
  • 22
  • 28
  • You can show it in a QLabel, like: `QLabel lbl("

    Kmax

    =

    K2

    .3"); lbl.show();`.
    – vahancho Apr 27 '15 at 09:59
  • Thanks for your answer, but I'am trying to print the text to a pdf file using QPrinter as a paint device – luffy Apr 27 '15 at 10:11
  • You can set that html code to a label, than grab the label's content as a pixmap and paint the text as an image with your printer. Otherwise there is no such function that supports drawing formulas. – vahancho Apr 27 '15 at 10:23
  • 1
    Try using unicode. Qt usually work good with it: https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts – Amartel Apr 27 '15 at 10:59
  • @vahancho you wrong, there is such function. Check my answer. – Dmitry Sazonov Apr 27 '15 at 11:14
  • @Amartel thanks. I tried using unicodes and it worked for defined characters but the "m" for example is missing – luffy Apr 27 '15 at 12:10

3 Answers3

31

Here is a full example using rich text of QTextDocument.

mainWindow.cpp:

#include "mainWindow.h"

void MainWindow::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    QTextDocument td;
    td.setHtml("K<sub>max</sub>=K<sub>2</sub> &middot; 3");
    td.drawContents(&painter);
}

If you need to draw the text at specific point, translate the coordinate system of the painter before drawing:

painter.translate(QPointF(50, 50));

mainWindow.cpp - Another solution:

#include "mainWindow.h"

void MainWindow::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    QTextDocument td;
    td.setHtml("K<sub>max</sub>=K<sub>2</sub> &middot; 3");
    QAbstractTextDocumentLayout::PaintContext ctx;
    ctx.clip = QRectF( 0, 0, 400, 100 );
    td.documentLayout()->draw( &painter, ctx );
}

mainWindow.h:

#include <QtGui>

class MainWindow: public QWidget
{
protected:
    void paintEvent(QPaintEvent*);
};

main.cpp:

#include <QtGui>
#include "mainWindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow mainWindow;
    mainWindow.show();
    return app.exec();
}

The project file:

TEMPLATE = app
QT += gui
HEADERS = mainWindow.h
SOURCES = main.cpp mainWindow.cpp

Result:

enter image description here

  • You have memory leak in `main`. But thatnks for writing samples to my answer :) – Dmitry Sazonov Apr 27 '15 at 11:34
  • 1
    Thanks, I tried this and it works fine for the position (0, 0), but as soon as I try to move the text to a predefined position in the page ("ctx.clip = QRectF( x, y, 400, 100 );") it disappears! Any ideas how I can fix this ? – luffy Apr 27 '15 at 12:15
  • 1
    Edited my answer to include this case. In brief, translate with "painter.translate(QPointF(50, 50));". – Mykhaylo Kopytonenko Apr 27 '15 at 12:36
  • If I need to draw at a specific point, isn't there any other way to do that than to translate the `QPainter` object? Maybe I have received a `QPainter` object as a function argument but have declared the argument `const`; then I won't be able to translate it. (A `QPainter` object cannot be copied either.) – HelloGoodbye Oct 07 '16 at 12:18
  • Any way to translate with a specific base line. For example I want my base line to be at (10,50), but translating it to (10,50) renders the text at (14,75). I now have trouble aligning text drawn with drawText. – RvdK Jan 25 '17 at 10:26
6

You may use supported Qt HTML subset to format your text. If you need to draw formatted text, you should use QTextDocument::drawContents.

QPainter::drawText is designed for plain text without formatting, and it works much faster.

Dmitry Sazonov
  • 8,801
  • 1
  • 35
  • 61
2

Since Qt 4.7, you can use QPainter.drawStaticText() with QStaticText:

painter = QPainter()
top_left = QPoint(0, 0)
painter.drawStaticText(top_left, QStaticText('foo<b>bar</b>'))

QStaticText will attempt to guess the format of the input text using Qt::mightBeRichText(), and interpret it as rich text if this function returns true.

If the limitations of QStaticText suit you (see class description), it should be much faster than QTextDocument.

K3---rnc
  • 6,717
  • 3
  • 31
  • 46