Qt / PyQt:低级文本渲染

0 投票
1 回答
820 浏览
提问于 2025-04-17 07:58

[注意:我更喜欢使用PyQt,但对我来说,Qt的答案是一样的。我理解这两种语言。]

问题:

我想显示一个字符串,比如:'Hello world!'(没什么特别的)。我不想通过代理,比如QTextEdit或QWebKit来实现。相反,我想在更低的层面上完全控制渲染——每个字符。以下是我的一些问题:

  1. 我应该使用哪个控件(为了更快的渲染)?QGraphicsWidget可以吗?

  2. 给定一个位置(x,y),我该如何在屏幕上渲染这个字符的图像?

  3. 文本可能会跨越多行。我是应该一个一个字符地渲染到屏幕上,还是先创建整行的“图像”,然后再渲染每一行(我想这样会加快滚动速度,因为不需要重新计算每个字符,只需上下移动整行)?如果是后者,我该如何创建那个图像?

  4. 当用户拖动鼠标选择文本时,我该如何高亮显示选中的部分?我需要重新渲染字符,还是只需在屏幕的那个位置做一些“背景颜色”的操作就可以了?

请以实用的方式回答我——也就是说,具体的方法/类等(不要只是模糊的想法,比如“显示它”——而是怎么做?)。

谢谢!

1 个回答

1

通过重写 QWidgetpaintEvent 方法并使用绘图工具来实现一个自定义的 QWidget,这是在 Qt 中使用小部件系统的最低级别。

这里有一个完整的 C++ 示例,我为你准备好了。我不太懂 PyQt,但希望你能把这个移植过去!

widget.h

#ifndef _WIDGET_H_
#define _WIDGET_H_

#include <QtGui>

class CustomPaint : public QWidget
{
    Q_OBJECT
    protected:
        virtual void paintEvent(QPaintEvent* event);
};

#endif

widget.cpp

#include "widget.h"

void CustomPaint::paintEvent(QPaintEvent* ev)
{
    QPainter painter(this);
    painter.setClipRect(ev->rect());
    painter.fillRect(ev->rect(), Qt::white);

    const int x = 10;
    const int y = 10;
    const int w = width() - 20;
    const int h = height() - 20;

    painter.setPen(QPen(QBrush(Qt::red), 0.0, Qt::DashLine));
    painter.drawRect(x, y, w, h);

    painter.setPen(QPen(QBrush(Qt::black), 0.0, Qt::SolidLine));
    painter.drawText(x, y, w, h,
        Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap,
        tr("Hello World"));
}

test.cpp

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

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    CustomPaint win;
    win.show();

    return app.exec();
}

test.pro

QT=core gui
HEADERS=widget.h
SOURCES=test.cpp widget.cpp

撰写回答