使用QPainter绘制丰富的文本

19

有没有一种方法可以绘制带有下标的固定文本。我的目标是得到类似这样的东西:“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);

我也尝试使用HTML标签格式化文本,但没有帮助(标签与文本一起打印出来):

我也试过用HTML标签格式化文本,但是并没有起到作用(标签和文本一起打印出来):

QString equation="<p>K<sub>max</sub></p>=<p>K<sub>2</sub></p>.3"

你可以在QLabel中显示它,例如:QLabel lbl("<p>K<sub>max</sub></p>=<p>K<sub>2</sub></p>.3"); lbl.show(); - vahancho
谢谢您的回答,但我正在尝试使用QPrinter作为绘图设备将文本打印到PDF文件中。 - luffy
您可以将HTML代码设置为标签,然后获取标签的内容作为像素图,并使用打印机将文本绘制为图像。否则,没有支持绘制公式的函数。 - vahancho
1
尝试使用Unicode。Qt通常与其兼容良好:https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts - Amartel
@vahancho,你错了,这个函数是存在的。请查看我的回答。 - Dmitry Sazonov
@Amartel 谢谢。我尝试使用 Unicode,已经为定义的字符工作了,但是例如“m”缺失了。 - luffy
3个回答

31

这是使用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);
}
如果您需要在特定点绘制文本,请在绘制前将绘图器的坐标系进行转换:
painter.translate(QPointF(50, 50));

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

主函数.cpp:

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

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

项目文件:

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

结果:

enter image description here


你的 main 函数存在内存泄漏问题。但是感谢你提供了示例来回答我的问题 :) - Dmitry Sazonov
1
谢谢,我尝试了这个方法,在位置(0,0)时能正常工作,但是一旦我尝试将文本移动到页面上的预定义位置("ctx.clip = QRectF(x,y,400,100);"),它就消失了!有什么办法可以修复这个问题吗? - luffy
1
编辑了我的答案以包括这种情况。简而言之,使用“painter.translate(QPointF(50, 50));”进行翻译。 - Mykhaylo Kopytonenko
如果我需要在特定点绘制,难道没有其他方法可以做到而不是转换QPainter对象吗?也许我已经作为函数参数接收了一个QPainter对象,但已将参数声明为const;那么我将无法进行转换。(QPainter对象也无法复制。) - HelloGoodbye
有没有一种特定的基线翻译方式?例如,我想让我的基线在(10,50),但将其翻译为(10,50)会使文本呈现在(14,75)。我现在无法对使用drawText绘制的文本进行对齐。 - RvdK

6
你可以使用支持的Qt HTML子集来格式化文本。如果需要绘制格式化文本,应该使用QTextDocument::drawContentsQPainter::drawText是为了纯文本而设计的,它的速度更快。

2

从Qt 4.7开始,您可以使用QPainter.drawStaticText()QStaticText

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

QStaticText 会使用 Qt::mightBeRichText() 来猜测输入文本的格式,如果该函数返回 true,则将其解释为富文本。

如果您满足 QStaticText 的限制(请参阅类描述),它应该比 QTextDocument 快得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接